<template>
  <div class="dt-talk-panel">
    <PublicContextMenu :pos="contextMenuPos" :data="contextMenuData" v-if="selectRecordId" @menuClick="menuClick" />
    <PublicEmojiList :pos="emojiPos" @sendEmoji="sendEmoji" v-if="isShowEmoji" />

    <div class="dt-chat-content-team">
      <div class="dt-chat-content-teamin" ref="scrollChat">
        <div class="dt-chat-content-more" v-if="isMoreCount">
          <el-button type="text" @click="getMoreChatList" :loading="lock.isMoreCount">更多消息</el-button>
        </div>
        <div
          v-for="(item, index) in chatList.item"
          :key="item.recordId"
          :class="['dt-chat-content-list', item.isShowReply ? 'dt-chat-curr' : '', item.userId == uid ? 'dt-chat-content-self' : '']"
          :ref="item.recordId"
        >
          <div class="dt-chat-content-info">
            <div class="dt-chat-content-user">
              <div
                class="dt-chat-content-headimg"
                @contextmenu.prevent.stop="showSendMenu($event, item, 'send', index, $refs.scrollChat, 'dt-chat-content-team')"
              >
                <el-image
                  :src="$tools.getStsFileUrl(secretUid, item.headImg)"
                  @click.stop="showSendHome($event, 'send', item, $refs.scrollChat, 'dt-chat-content-team')"
                  @load="$tools.loadImgCenter($event, 26)"
                >
                  <div slot="placeholder" class="image-slot">
                    <i class="el-icon-loading"></i>
                  </div>
                </el-image>
                <i v-if="item.toWho" class="dt-chat-content-name-img dt-chat-content-name-imgat"></i>
                <i v-if="item.privateUserId" class="dt-chat-content-name-img dt-chat-content-name-imgsl"></i>
                <ul v-show="item.isShowSendMenu && item.userId != uid" :class="[isCardUp ? 'up' : '']">
                  <li @click="appendAtuser('panel', item.userId, item.userName)">@{{ item.userName }}</li>
                  <li @click="appendPrivate('panel', item.userId, item.userName)">悄悄话</li>
                  <li @click="appendReceipt('panel', item.userId, item.userName)">回执消息</li>
                  <!-- <li @click="enterPureMode(item.user_id)">纯净模式</li> -->
                </ul>
                <!-- 个人信息卡片 -->
                <el-card :class="['box-card', 'dt-home-info', isCardUp ? 'up' : '']" v-show="item.isShowSendHome">
                  <div v-show="!homeInfo.id" v-loading="true" element-loading-text="拼命加载中" element-loading-spinner="el-icon-loading"></div>
                  <dl v-show="homeInfo.id">
                    <dt>
                      <div class="dt-home-head-img">
                        <el-image :src="$tools.getStsFileUrl(secretUid, item.headImg)" alt="" @load="$tools.loadImgCenter($event, 52)">
                          <div slot="placeholder" class="image-slot">
                            <i class="el-icon-loading"></i>
                          </div>
                        </el-image>
                      </div>
                      <div class="dt-home-realName">
                        <div>
                          <h3>{{ homeInfo.certificateName ? homeInfo.certificateName : 'UID' + homeInfo.id }}</h3>
                          <i v-if="homeInfo.gender != 0" :class="{ boy: homeInfo.gender == 1 }"></i>
                        </div>
                        <p class="dt-home-uid">UID{{ homeInfo.id }}</p>
                      </div>
                    </dt>
                    <dd class="dt-home-dd">
                      <div>
                        <span class="dt-home-label">地区</span>
                        <span class="dt-home-cont">{{ homeInfo.liveplace ? homeInfo.liveplace : '暂未设置' }}</span>
                      </div>
                      <div>
                        <span class="dt-home-label">
                          IP
                          <el-popover
                            popper-class="home-popover"
                            placement="top-start"
                            title="响应「互联网用户账号信息管理规定」，维护网络安全，展示IP属地"
                            width="200"
                            trigger="hover"
                            content="IP 属地以网络运营商提供的信息为准，与地理位置可能不一致"
                          >
                            <template #reference>
                              <i class="el-icon-question" style="cursor: pointer; color: #ced2db; font-size: 16px"></i>
                            </template>
                          </el-popover>
                        </span>
                        <span class="dt-home-cont">{{ homeInfo.lastLoginAddress ? homeInfo.lastLoginAddress : '暂未设置' }}</span>
                      </div>
                    </dd>
                    <dd>
                      <div>
                        <span class="dt-home-label">个性签名</span>
                        <span class="dt-home-cont">{{ homeInfo.personalSignature ? homeInfo.personalSignature : '暂未设置' }}</span>
                      </div>
                    </dd>
                  </dl>
                </el-card>
              </div>
              <div class="dt-chat-content-name">
                <em v-if="item.privateUserId" class="dt-chat-content-words-sl">{{ item.userName + ' 私聊 ' + item.privateUserName }}</em>
                <em v-else>{{ item.userName }}</em>
              </div>
            </div>
            <div class="dt-chat-content-words" v-if="item.messageType == 1">
              <div class="dt-chat-content-words-box" @contextmenu.prevent.stop="showOprs($event, item, index)">
                <span v-for="(items, index) in item.message.message" :key="index + items.content + generateTimestamp()">
                  <em
                    :class="[
                      { 'dt-chat-content-words-at': item.toWho != null },
                      { 'dt-chat-content-words-sl': !!item.privateUserId },
                      { 'dt-chat-content-words-bold': items.bold == 'true' }
                    ]"
                    v-html="getHttpsText(items.content)"
                    @click.prevent="goHttpsLink($event)"
                  ></em>
                </span>
              </div>
            </div>
            <div class="dt-chat-content-words" v-if="item.messageType == 2">
              <div class="dt-chat-content-words-box" @contextmenu.prevent.stop="showOprs($event, item, index)">
                <span v-for="(items, index) in item.message.message" :key="index + items.content + generateTimestamp()">
                  <em
                    :class="[{ 'dt-chat-content-words-at': item.toWho != null }, { 'dt-chat-content-words-sl': !!item.privateUserId }]"
                    v-html="getHttpsText(items.content)"
                    @click.prevent="goHttpsLink($event)"
                  ></em>
                  <br v-if="items.wrap == 'true'" />
                </span>
              </div>
              <span
                v-if="item.singleReceiptState != 1 && item.singleReceiptUid == uid"
                @click="sureReceipt(item, '1')"
                class="dt-chat-content-words-at-receipt"
                ><em class="el-icon-message-solid"></em
              ></span>
              <span v-if="!!item.singleReceiptState == 0 && item.userId == uid && item.singleReceiptUid" class="dt-chat-content-words-at-receipt"
                ><i class="dt-chat-content-words-at-receipt-circle"></i
              ></span>
              <span
                v-if="item.singleReceiptState == 1 && (item.singleReceiptUid == uid || item.userId == uid)"
                class="dt-chat-content-words-at-check"
              >
                <el-tooltip
                  :open-delay="500"
                  class="item"
                  effect="light"
                  :content="item.singleReceiptUserName + ' ' + item.singleReceiptTime + ' 已回执'"
                  placement="top"
                >
                  <em class="el-icon-circle-check"></em>
                </el-tooltip>
              </span>
            </div>
            <div class="dt-chat-content-words" v-if="item.messageType == 3">
              <div class="dt-chat-content-words-box" @contextmenu.prevent.stop="showOprs($event, item, index)">
                <div v-if="item.message.message.length === 1" class="dt-chat-1imgs">
                  <!-- <p class="dt-chat-content-words-receipt-tip" v-if="!!item.singleReceiptUid">{{item.toWhoNames}}</p> -->
                  <p class="dt-chat-content-words-receipt-tip" v-if="!!item.toWho">{{ item.toWhoNames }}</p>
                  <el-image
                    v-for="(items, index) in item.message.message"
                    :key="items.fileUrl"
                    :initial-index="index"
                    :src="$tools.getStsFileUrl(secretUid, items.fileUrl, '100h_100w_1e')"
                    :alt="items.fileName"
                    :preview-src-list="
                      (() => {
                        return item.message.message.map((items) => {
                          return $tools.getStsFileUrl(secretUid, items.fileUrl)
                        })
                      })()
                    "
                    @load="
                      $tools.loadImgCenter($event, null, () => {
                        if (loadDirection === 'bottom') {
                          handleScrollBottom('1')
                        }
                      })
                    "
                  >
                    <div slot="placeholder" class="image-slot">
                      <i class="el-icon-loading"></i>
                    </div>
                  </el-image>
                </div>
                <div v-else-if="item.message.message.length > 1" class="dt-chat-9imgs">
                  <!-- <p class="dt-chat-content-words-receipt-tip" v-if="item.singleReceiptUid">{{item.toWhoNames}}</p> -->
                  <p class="dt-chat-content-words-receipt-tip" v-if="!!item.toWho">{{ item.toWhoNames }}</p>
                  <el-image
                    v-for="(items, index) in item.message.message"
                    :key="items.fileUrl"
                    :initial-index="index"
                    :src="$tools.getStsFileUrl(secretUid, items.fileUrl, '100h_100w_1e')"
                    :alt="items.fileName"
                    :preview-src-list="
                      (() => {
                        return item.message.message.map((items) => {
                          return $tools.getStsFileUrl(secretUid, items.fileUrl)
                        })
                      })()
                    "
                    @load="
                      $tools.loadImgCenter($event, 100, () => {
                        if (loadDirection === 'bottom') {
                          handleScrollBottom('2')
                        }
                      })
                    "
                  >
                    <div slot="placeholder" class="image-slot">
                      <i class="el-icon-loading"></i>
                    </div>
                  </el-image>
                </div>
              </div>
              <span
                v-if="item.singleReceiptState != 1 && item.singleReceiptUid == uid"
                @click="sureReceipt(item, '1')"
                class="dt-chat-content-words-at-receipt"
                ><em class="el-icon-message-solid"></em
              ></span>
              <span v-if="!!item.singleReceiptState == 0 && item.userId == uid && item.singleReceiptUid" class="dt-chat-content-words-at-receipt"
                ><em class="dt-chat-content-words-at-receipt-circle"></em
              ></span>
              <span
                v-if="item.singleReceiptState == 1 && (item.singleReceiptUid == uid || item.userId == uid)"
                class="dt-chat-content-words-at-check"
              >
                <el-tooltip
                  :open-delay="500"
                  class="item"
                  effect="light"
                  :content="item.singleReceiptUserName + ' ' + item.singleReceiptTime + ' 已回执'"
                  placement="top"
                >
                  <em class="el-icon-circle-check"></em>
                </el-tooltip>
              </span>
            </div>
            <div class="dt-chat-content-words" v-if="item.messageType == 4">
              <div class="dt-chat-content-words-box" @contextmenu.prevent.stop="showOprs($event, item, index)">
                <!-- <p class="dt-chat-content-words-receipt-tip" v-if="item.singleReceiptUid">{{item.toWhoNames}}</p> -->
                <p class="dt-chat-content-words-receipt-tip" v-if="!!item.toWho">{{ item.toWhoNames }}</p>
                <div class="dt-chat-content-words-receipt-card" @click="downFile(item)">
                  <div>
                    <img :src="currFilecon(item.message.message[0])" alt="" />
                  </div>
                  <div>
                    <!-- <p class="mb4">{{ item.message.message[0].fileName }}</p> -->
                    <p class="mb4" :title="item.message.message[0].fileName">{{ item.message.message[0].fileName }}</p>
                    <p class="colorb-3">{{ $tools.convertUnit(item.message.message[0].fileSize) }}</p>
                  </div>
                </div>
                <!-- <a v-else :href="$tools.getStsFileUrl(secretUid,item.message.message[0].fileUrl)" target="_blank" class="dt-mess-file">[ <i
                    class="el-icon-document"></i>
                  {{item.message.message[0].fileName}}]</a> -->
              </div>
              <span
                v-if="item.singleReceiptState != 1 && item.singleReceiptUid == uid"
                @click="sureReceipt(item, '1')"
                class="dt-chat-content-words-at-receipt"
                ><em class="el-icon-message-solid"></em
              ></span>
              <span v-if="!!item.singleReceiptState == 0 && item.userId == uid && item.singleReceiptUid" class="dt-chat-content-words-at-receipt"
                ><em class="dt-chat-content-words-at-receipt-circle"></em
              ></span>
              <span
                v-if="item.singleReceiptState == 1 && (item.singleReceiptUid == uid || item.userId == uid)"
                class="dt-chat-content-words-at-check"
              >
                <el-tooltip
                  :open-delay="500"
                  class="item"
                  effect="light"
                  :content="item.singleReceiptUserName + ' ' + item.singleReceiptTime + ' 已回执'"
                  placement="top"
                >
                  <em class="el-icon-circle-check"></em>
                </el-tooltip>
              </span>
            </div>
            <div class="dt-chat-content-words" v-if="item.messageType == 7">
              <div class="dt-chat-content-words-card" @click="showReceiptCard(item)">
                <el-card class="box-card" shadow="never">
                  <!-- <el-tooltip :open-delay="500"  effect="dark" :content="item.message.message[0].title" placement="top-start"> -->
                  <div class="dt-chat-content-words-card-title">
                    {{ item.message.message[0].title }}
                  </div>
                  <!-- </el-tooltip> -->
                  <div class="dt-chat-content-words-card-dec" v-if="item.receiptEndTime">截止时间：{{ item.receiptEndTime.substring(0, 16) }}</div>
                  <!-- <el-tooltip :open-delay="500"  effect="dark" :content="item.message.message[0].description" placement="top-start"> -->
                  <div class="dt-chat-content-words-card-dec">
                    描述：{{ item.message.message[0].description ? item.message.message[0].description : '暂无内容' }}
                  </div>
                  <!-- </el-tooltip> -->
                  <!-- <el-tooltip :open-delay="500"  effect="dark" :content="item.message.message[0].joinUserNames" placement="top-start"> -->
                  <div class="dt-chat-content-words-card-dec mt8 mb12">参与人：{{ item.message.message[0].joinUserNames }}</div>
                  <!-- </el-tooltip> -->

                  <div class="dt-chat-content-words-card-line"></div>
                  <div class="dt-chat-content-words-card-dec dt-chat-content-words-card-btn mt12">
                    <span class="dt-chat-content-words-card-receipt">已回执：{{ item.confirmUserCount }}/{{ item.totalUserCount }}</span>
                    <span class="dt-chat-content-words-card-receipt" v-show="item.receiptButtonState == 1">
                      <el-button type="primary" size="small" @click.stop="sureReceipt(item, '2')">确定回执</el-button></span
                    >
                    <span class="dt-chat-content-words-card-receipt" v-show="item.receiptButtonState == 2 || item.receiptButtonState == 3">
                      <el-button type="primary" size="small" disabled>{{ item.receiptButtonState == 2 ? '已回执' : '确定回执' }}</el-button></span
                    >
                  </div>
                </el-card>
              </div>
            </div>
            <div class="dt-chat-content-words" v-if="item.messageType == 6">
              <div class="dt-chat-content-words-box dt-chat-content-words-box-voice" @contextmenu.prevent.stop="showOprs($event, item, index)">
                <div
                  class="voice-message"
                  :style="{ width: voiceMessageWidth(item.message.message[0].duration) }"
                  @click="playOrPauseVoice($event, item)"
                >
                  <span class="icon paused"></span><span class="audio-length">{{ item.message.message[0].duration }}''</span>
                  <div class="dt-chat-content-words-origin" v-if="item.isPlayed == 0"></div>
                </div>
                <div class="voice-text" v-if="item.message.message[0].text && item.isShowText">
                  <p>
                    {{ item.message.message[0].text }}
                  </p>
                </div>
                <div class="voice-text" v-if="!item.message.message[0].text && item.isShowText">
                  <p
                    v-loading="!item.message.message[0].text"
                    element-loading-spinner="el-icon-loading"
                    element-loading-background="rgba(0, 0, 0, 0)"
                  ></p>
                </div>
              </div>
            </div>
            <div class="dt-chat-content-time">
              <span class="dt-chat-content-chatTime">{{ item.createTime | filterTimeStamp }}</span>
              <!-- <a v-if="item.originalId" class="dt-chat-content-replyclick" href="javascript:void(0)" @click="goBack(item, index)">返回原消息</a> -->
              <!-- <a
                v-if="item.disableComment == 0 && item.userId != -2 && item.messageType != 7"
                class="dt-chat-content-replyclick"
                href="javascript:void(0)"
                @click="showReply(item, index)"
                >讨论本条</a
              >
              <a
                v-if="item.userId == uid && item.messageType != 7"
                class="dt-chat-content-replyclick"
                href="javascript:void(0)"
                @click=" (item)"
                >{{ item.disableComment == 0 ? '关闭评论' : '开启评论' }}</a
              >
              <a
                v-if="item.canDelete == 1 && item.userId == uid"
                class="dt-chat-content-replyclick"
                href="javascript:void(0)"
                @click="delRecord(item, index)"
                >删除消息</a
              >
              <a v-if="item.originalId" class="dt-chat-content-replyclick" href="javascript:void(0)" @click="goBack(item, index)">返回原消息</a>
              <a
                v-if="item.userId != uid && item.userId != -2 && item.messageType != 7"
                class="dt-chat-content-replyclick"
                href="javascript:void(0)"
                @click="report(item)"
                >举报</a
              > -->
              <span v-if="item.messageTip" class="dt-report-tip"><i class="el-icon-warning-outline"></i>{{ item.messageTip }}</span>
            </div>
            <div class="dt-chat-content-reply" v-if="item.isShowReply">
              <el-input type="textarea" maxlength="100" placeholder="请输入内容" v-model="item.replyTxt"> </el-input>
              <div class="dt-chat-content-replybtn">
                <i class="dt-el-icon dt-icon-emoji" @click.stop="(e) => showEmoji(e, index)" title="添加表情"><img src="/skb/img/emoji.svg" alt="" /></i>
                <i class="dt-el-icon el-icon-picture-outline" @click="showFileInput('Replyimg', item, index)" title="添加图片"></i>
                <!-- <el-button type="primary" size="mini" @click="showFileInput('Replyimg', item, index)" :loading="replyLoad[index]">添加图片</el-button> -->
                <el-button
                  class="r"
                  style="margin-left: 10px"
                  type="primary"
                  plain
                  size="mini"
                  @click="showReply(item, index)"
                  :loading="replyLoad[index]"
                  >取消</el-button
                >
                <el-button class="r" type="primary" size="mini" @click="sendReplyInfo(item, index, '2')" :loading="replyLoad[index]">确定</el-button>
              </div>
            </div>
            <div class="dt-chat-content-reply-info" v-if="item.disableComment == 0 && item.replyCount > 0">
              <div class="dt-chat-content-reply-info-list" v-for="items in item.reply" :key="items.replyId">
                <div class="dt-chat-content-reply-userInfo">
                  <a class="dt-chat-content-reply-info-name" href="javascript:void(0)">{{ items.userName }} :</a>
                  <span
                    v-if="items.messageType == '3'"
                    :class="['dt-chat-content-reply-info-words', { 'dt-chat-content-reply-info-words-sl': !!item.privateUserId }]"
                  >
                    <a href="javascript:void(0)" @click="showReplyImg($event)">
                      {{ items.shortMessage }}
                      <el-image
                        :src="$tools.getStsFileUrl(secretUid, JSON.parse(items.message).message[0].fileUrl, '100h_100w_1e')"
                        :preview-src-list="[$tools.getStsFileUrl(secretUid, JSON.parse(items.message).message[0].fileUrl)]"
                        @load="
                          $tools.loadImgCenter($event, null, () => {
                            if (loadDirection === 'bottom') {
                              handleScrollBottom('1')
                            }
                          })
                        "
                      >
                        <div slot="placeholder" class="image-slot">
                          <i class="el-icon-loading"></i>
                        </div>
                      </el-image>
                    </a>
                  </span>
                  <span v-else>
                    <span
                      v-for="(currentItem, index) in JSON.parse(items.message).message"
                      :key="index + currentItem.content + generateTimestamp()"
                      :class="['dt-chat-content-reply-info-words', { 'dt-chat-content-reply-info-words-sl': !!item.privateUserId }]"
                      v-html="getHttpsText(currentItem.content)"
                      @click.prevent="goHttpsLink($event)"
                    ></span>
                  </span>
                </div>
                <div class="dt-chat-content-reply-time">
                  {{ items.createTime }}
                  <a v-if="items.userId != uid" class="dt-chat-content-replyclick recover" href="javascript:void(0)" @click="report(item, items)"
                    >举报</a
                  >
                  <span v-if="items.messageTip" class="dt-report-tip"><i class="el-icon-warning-outline"></i>{{ items.messageTip }}</span>
                </div>
              </div>
              <div v-if="item.isShowMoreCount" class="dt-chat-content-reply-info-review">
                <a href="javascript:void(0)" @click="getReplyList(item)">展开 </a>
              </div>
              <div v-if="!item.isShowMoreCount && item.replyCount > 3" class="dt-chat-content-reply-info-review">
                <a href="javascript:void(0)" @click="foldReplyList(item)">收起</a>
              </div>
            </div>
          </div>
        </div>
        <input type="file" @change="fileChage($event, 'Replyimg')" ref="fileInputReplyimg" style="display: none" accept=".jpg,.jpeg,.png,.gif" />
      </div>
      <div class="dt-chat-content-chattip">
        <ul>
          <li>
            <a
              href="javascript:void(0)"
              @click="clearAtmeuser"
              class="dt-chat-tip-yellow"
              v-show="atMeuser && atMeuser.message && atMeuser.message.length > 0"
              >{{ atMessageText }}</a
            >
          </li>
          <li>
            <a
              href="javascript:void(0)"
              @click="clearPrivateuser"
              class="dt-chat-tip-purple"
              v-show="privateUser && privateUser.message && privateUser.message.length > 0"
              >{{ privateUserText }}</a
            >
          </li>
          <li>
            <a
              href="javascript:void(0)"
              @click="clearReplyUser"
              class="dt-chat-tip-black"
              v-show="replyUser && replyUser.message && replyUser.message.length > 0"
              >{{ replyText }}</a
            >
          </li>
        </ul>
      </div>
    </div>
    <el-dialog title="回执消息" class="receiptBox" top="25vh" :visible.sync="receiptShow" :modal-append-to-body="false" :width="receiptWidth">
      <div class="dt-receipt-content">
        <div class="dt-receipt-content-left">
          <div class="dt-receipt-content-left-title">
            {{ receiptInfo.title }}
          </div>
          <div class="dt-receipt-content-left-join">
            <div style="margin-bottom: 14px" v-if="receiptInfo.endTime">
              <em class="el-icon-alarm-clock"></em> <span>截止时间：{{ receiptInfo.endTime.substring(0, 16) }}</span>
            </div>
            <div>
              <em class="el-icon-user"></em> <span>参与人：{{ receiptInfo.joinUserName }}</span>
            </div>
          </div>
          <div class="dt-receipt-content-left-dec">
            <em>描述</em><span style="white-space: pre-wrap">{{ receiptInfo.description ? receiptInfo.description : '暂无内容' }}</span>
          </div>
          <div class="dt-receipt-content-left-file">
            <div class="dt-receipt-content-left-file-left">
              <span>附件</span>
            </div>
            <div class="dt-receipt-content-left-file-right" v-if="receiptInfo.fileList && receiptInfo.fileList.length > 0">
              <div v-for="item in receiptInfo.fileList" :key="item.fileUrl">
                <em class="el-icon-document"></em>
                <span>{{ item.fileName }}</span>
                <span v-if="receiptInfo.canDownloadFile == 1"><el-button type="text" @click="downReceiptFile(item)">下载</el-button></span>
              </div>
            </div>
            <div class="dt-receipt-content-left-file-right-none" v-else>
              <div>暂无内容</div>
            </div>
          </div>
          <div class="dialog-footer" v-show="receiptInfo.receiptButtonState != 0">
            <el-button type="primary" @click="sureReceipt(receiptInfo, '3')" size="small" v-show="receiptInfo.receiptButtonState == 1"
              >确定回执</el-button
            >
            <el-button type="primary" disabled size="small" v-show="receiptInfo.receiptButtonState == 2 || receiptInfo.receiptButtonState == 3">{{
              receiptInfo.receiptButtonState == 2 ? '已回执' : '确定回执'
            }}</el-button>
          </div>
          <!-- <div slot="footer" class="dialog-footer">

          </div> -->
        </div>
        <div class="dt-receipt-content-right" v-if="receiptInfo.isCreator == 1">
          <el-tabs v-model="activeName" @tab-click="handleClick">
            <el-tab-pane label="回执情况" name="first">
              <div class="dt-receipt-content-right-top">
                <p>已回执 {{ receiptInfo.confirmUserCount }}/{{ receiptInfo.totalUserCount }}</p>
              </div>
              <div class="dt-receipt-content-right-receipt-list" v-for="item in receiptInfo.confirmLog" :key="item.id">
                <span>{{ item.userName }}</span>
                <span>{{ item.createTime }}</span>
                <span>已回执</span>
              </div>
            </el-tab-pane>
            <el-tab-pane label="下载记录" name="second">
              <el-table :data="receiptInfo.downloadLog" style="width: 100%;overflow" :header-cell-style="headerRowStyle">
                <el-table-column prop="userName" label="姓名" width="70" :show-overflow-tooltip="true" tooltip-effect="dark"> </el-table-column>
                <el-table-column prop="remark" label="文件名称" width="120" :show-overflow-tooltip="true" tooltip-effect="dark"> </el-table-column>
                <el-table-column prop="createTime" label="下载时间" width="130" :show-overflow-tooltip="true" tooltip-effect="dark">
                </el-table-column>
              </el-table>
            </el-tab-pane>
          </el-tabs>
        </div>
      </div>
    </el-dialog>
    <!--举报-->
    <el-dialog
      class="dt-report-group"
      title="举报"
      :visible.sync="reportIsShow"
      :append-to-body="true"
      width="680px"
      :show-close="false"
      :close-on-press-escape="false"
      :close-on-click-modal="false"
    >
      <div class="dt-report-cont">
        <h6>
          举报<span class="dt-name">{{ reportCont.userName }}</span
          >的消息:
        </h6>
        <div class="dt-report-recover" v-if="reportCont.messageType == '2'">
          <span>{{ reportCont.userName }}：</span>
          <div>
            <span v-for="item in reportCont.message" :key="item.content">{{ item.content }}<br v-if="item.wrap == 'true'" /></span>
          </div>
        </div>
        <p class="dt-report-recover" v-else>
          <span>{{ reportCont.userName }}：{{ reportCont.shortMessage }}</span>
          <span v-for="item in reportCont.message" :key="item.fileName">
            <em v-if="item.duration">{{ item.duration }}''</em></span
          >
        </p>
        <el-form label-position="left" :model="reportRuleForm" :rules="reportRules" ref="reportRuleForm" label-width="100px" class="dt-report-radio">
          <el-form-item label="举报类型" prop="reportType">
            <el-radio-group v-model="reportRuleForm.reportType">
              <el-radio :label="1">垃圾广告</el-radio>
              <el-radio :label="2">低俗色情</el-radio>
              <el-radio :label="3">人身攻击</el-radio>
              <el-radio :label="4">其他有害</el-radio>
            </el-radio-group>
          </el-form-item>
        </el-form>
      </div>
      <div slot="footer">
        <el-button size="medium" type="primary" @click="submitFormReport('reportRuleForm')" :loading="lock.report">确 定</el-button
        ><el-button size="medium" @click="resetFormReport('reportRuleForm')">取 消</el-button>
      </div>
    </el-dialog>
    <!-- <el-dialog :visible.sync="isShowReplyImg" :modal-append-to-body="false" :width="dialogWidth" @close="closeReplyImg">
      <img :src="this.replyImgSrc" :style="{ maxWidth: '100%', height: 'auto' }" @load="onImageLoad" alt="大图" />
    </el-dialog> -->
  </div>
</template>
<script>
import BenzAMRRecorder from 'benz-amr-recorder'
/*  获取年月日时分秒 */
const getDateFormatString = function (type, timestamp) {
  var date = timestamp ? new Date(timestamp) : new Date(),
    dateStr = ''
  var y = date.getFullYear()
  var m = date.getMonth() + 1
  m = m < 10 ? '0' + m : m
  var d = date.getDate()
  d = d < 10 ? '0' + d : d
  var h = date.getHours()
  h = h < 10 ? '0' + h : h
  var min = date.getMinutes()
  min = min < 10 ? '0' + min : min
  var s = date.getSeconds()
  s = s < 10 ? '0' + s : s
  switch (type) {
    case 'md':
      dateStr = m + '-' + d
      break
    case 'mdhms':
      dateStr = m + '-' + d + ' ' + h + ':' + min + ':' + s
      break
    case 'ymd':
      dateStr = y + '-' + m + '-' + d
      break
    case 'ymdhms':
      dateStr = y + '-' + m + '-' + d + ' ' + h + ':' + min + ':' + s
      break
    default:
      dateStr = y + '' + m + '' + d + '' + h + '' + min + '' + s
      break
  }
  return dateStr
}
/* 获取格式化的时间戳（距离当前时间有多久） */
const getChatTimeString = function (timestamp) {
  var currDate = new Date(),
    currTimestamp = currDate.getTime(),
    timeLong = currTimestamp - timestamp,
    timeStr = ''
  if (timeLong <= 60 * 1000) {
    timeStr = '刚刚'
  } else if (timeLong > 60 * 1000 && timeLong <= 2 * 60 * 1000) {
    timeStr = '1分钟前'
  } else if (timeLong > 2 * 60 * 1000 && timeLong <= 60 * 60 * 1000) {
    var min = Math.floor(timeLong / 1000 / 60)
    timeStr = min + '分钟前'
  } else if (timeLong > 60 * 60 * 1000 && timeLong <= 24 * 60 * 60 * 1000) {
    var min = Math.floor(timeLong / 1000 / 60 / 60)
    timeStr = min + '小时前'
  } else if (timeLong > 24 * 60 * 60 * 1000) {
    var currYear = currDate.getFullYear(),
      timeYear = new Date(timestamp).getFullYear()
    if (currYear === timeYear) {
      //今年内
      timeStr = getDateFormatString('mdhms', timestamp)
    } else {
      //跨年
      timeStr = getDateFormatString('ymdhms', timestamp)
    }
  }
  return timeStr
}
export default {
  head() {
    return {
      script: [
        {
          //天翼云
          type: 'text/javascript',
          src: 'https://www.ccccdt.com/skb/js/oos-sdk-6.0.min.js'
        }
      ]
    }
  },
  data() {
    return {
      secretUid: this.$store.state.uid,
      uid: this.$tools.getDecrypt(this.$store.state.uid), //用户id
      isMoreCount: true,
      lock: { isMoreCount: false, atUser: false, sendMess: false, report: false }, //sendImg: false, sendFile: false,
      // 聊天记录
      chatList: {},
      /**
       * 控制初始化数据时的loadding展示
       */
      isShowLodding: false,
      // 判断个人信息页面显示位置
      isCardUp: false,
      // 个人信息
      homeInfo: {},
      loadDirection: 'bottom', //初始加载方向向下,
      // 查看回执消息卡片
      receiptShow: false,
      receiptInfo: '',
      // 回执消息详情标签页
      activeName: 'first',
      //评论的lodding
      replyLoad: [],
      //递归状态控制回到历史消息之后加载历史消息之后的消息
      recursionState: false,
      // 举报弹窗是否显示
      reportIsShow: false,
      reportCont: {
        message: '',
        userName: '',
        groupId: '',
        recordId: '',
        replyId: '',
        messageType: '',
        shortMessage: ''
      },
      reportRuleForm: {
        reportType: ''
      },
      reportRules: {
        reportType: [{ required: true, message: '请选择举报类型', trigger: 'change' }]
      },
      recordItem: null,
      replyIndex: '',
      // 艾特我的用户列表
      atMeuser: {},
      // 私聊我的用户列表
      privateUser: {},
      // 评论我的用户列表
      replyUser: {},
      // 回执消息弹窗宽度限制
      receiptWidth: '1040px',
      // 讨论本条图片预览
      // isShowReplyImg: false,
      // 显示回复图片的弹框默认宽度
      // dialogWidth: '50%', // 默认宽度
      // replyImgSrc: '',
      /***************消息提示*****************************/
      msgTime: 0,
      msgTitle: '数科帮网页版',
      msgTimer: null,
      // 语音播放相关参数
      groupName: '',
      selectRecordId: '', // 右键id
      contextMenuPos: {}, // 定位
      contextMenuData: [],
      isShowEmoji: false,
      emojiPos: {},
      replyIndex: -1
    }
  },
  computed: {
    query() {
      return this.$tools.getQuery(this)
    },
    atMessageText() {
      if (this.atMeuser && this.atMeuser.message && this.atMeuser.message.length > 0) {
        return this.atMeuser.message.length === 1 ? this.atMeuser.message[0].username + '@你' : this.atMeuser.message.length + '人@你'
      }
      return '' // 如果atMeuser.message不存在或为空，则返回空字符串
    },
    privateUserText() {
      if (this.privateUser && this.privateUser.message && this.privateUser.message.length > 0) {
        return this.privateUser.message.length === 1 ? this.privateUser.message[0].username + '私聊你' : this.privateUser.message.length + '人私聊你'
      }
      return '' // 如果atMeuser.message不存在或为空，则返回空字符串
    },
    replyText() {
      if (this.replyUser && this.replyUser.message && this.replyUser.message.length > 0) {
        return this.replyUser.message.length === 1 ? this.replyUser.message[0].username + '评论你' : this.replyUser.message.length + '人评论你'
      }
      return '' // 如果atMeuser.message不存在或为空，则返回空字符串replyUser
    }
  },
  filters: {
    filterTimeStamp(val) {
      return getChatTimeString(new Date(val).getTime())
    },
    kbToMb(kb, precision = 2) {
      // if (isNaN(kb)) return kb // 如果输入不是数字，直接返回原始值
      // return (kb / (1024 * 1024)).toFixed(2) //toFixed(2) 保留两位小数
      if (isNaN(kb)) return kb // 如果输入不是数字，直接返回原始值
      let result = kb / (1024 * 1024) // 转换为MB
      result = parseFloat(result.toFixed(precision)) // 保留指定位数的小数
      return result < 0.01 ? 0.01 : result // 如果结果小于0.01，则返回0.01，否则返回计算结果
    }
  },
  methods: {
    // 发送emoji
    sendEmoji(emoji) {
      this.chatList.item[this.replyIndex].replyTxt += emoji
    },
    showEmoji(event, index) {
      this.isShowEmoji = true
      this.replyIndex = index
      let wrapperDom = document.querySelector('.dt-talk-panel')

      this.emojiPos = {
        x: event.pageX - 356,
        y: event.pageY - 66
      }
      if (wrapperDom.clientHeight - this.emojiPos.y < 120) {
        this.emojiPos.y -= 300
      }
      console.log('wrapperDom========', wrapperDom.clientHeight, this.emojiPos)
    },
    menuClick(item) {
      console.log('menuClick==========', item)
      if (item.key == 1) {
        this.showReply(item.item, this.selectRecordIndex)
      } else if (item.key == 2) {
        this.report(item.item)
      } else if (item.key == 3) {
        this.closeReply(item.item)
      } else if (item.key == 4) {
        this.delRecord(item.item, this.selectRecordIndex)
      } else if (item.key == 5) {
        this.showText(item.item)
      } else if (item.key == 6) {
        this.goBack(item.item, this.selectRecordIndex)
      }
    },
    //右键菜单
    showOprs(event, item, index) {
      this.contextMenuPos = {
        x: event.pageX - 350,
        y: event.pageY - 85
      }

      this.contextMenuData = []

      if (item.disableComment == 0 && item.userId != -2 && item.messageType != 7) {
        this.contextMenuData.push({
          label: '评论',
          key: 1,
          item
        })
      }
      if (item.userId != this.uid && item.userId != -2 && item.messageType != 7) {
        this.contextMenuData.push({
          label: '举报',
          key: 2,
          item
        })
      }
      if (item.userId == this.uid && item.messageType != 7) {
        this.contextMenuData.push({
          label: item.disableComment == 0 ? '关闭评论' : '开启评论',
          key: 3,
          item
        })
      }
      if (item.canDelete == 1 && item.userId == this.uid) {
        this.contextMenuData.push({
          label: '删除消息',
          key: 4,
          item
        })
      }
      if (item.messageType == 6 && !item.isShowText) {
        this.contextMenuData.push({
          label: '转文字',
          key: 5,
          item
        })
      }
      if (item.originalId) {
        this.contextMenuData.push({
          label: '返回原消息',
          key: 6,
          item
        })
      }

      if (!this.contextMenuData.length) return
      this.selectRecordIndex = index
      this.selectRecordId = item.recordId
    },
    // 获取初始聊天记录
    getChatList() {
      var data = [
          {
            groupId: this.query.groupId,
            pageSize: '10',
            userId: this.uid,
            lastTime: '',
            nextTime: '',
            privateUserId: '',
            recordId: '',
            singleReceiptUid: ''
          }
        ],
        domain = [this.$store.state.DOMAIN],
        path = ['/project/customGroup/recordList'],
        dataAxios = this.$tools.getDataAxios(this, domain, path, data)
      Promise.all(dataAxios)
        .then((response) => {
          this.$tools.callbackAxios(this, response, (response) => {
            var data = response[0].data
            if (data.code === 200) {
              this.isShowLodding = false
              this.groupName = data.data.groupName
              if (data.data.moreCount > 0) {
                this.isMoreCount = true
              } else {
                this.isMoreCount = false
              }
              data.data.item.forEach((item) => {
                item.message = JSON.parse(item.message)
                if (item.replyCount > 3) {
                  item.isShowMoreCount = true
                } else {
                  item.isShowMoreCount = false
                }
                item.isShowSendMenu = false
                item.isShowSendHome = false
                item.isShowReply = false
                item.replyTxt = ''
                item.replyImgSrc = ''
                if (item.messageType == 6) {
                  item.isPlayer = false
                  item.isShowText = false
                }
              })
              this.chatList = { ...data.data }
              this.handleScrollBottom('3')
              if (this.query.recordId) {
                this.$nextTick(() => {
                  this.goBack({ recordId: this.query.recordId }, 'undefined', '3')
                })
              }
            } else if (data.code === 457) {
              this.$emit('changeRules')
              this.chatList = {}
            }
          })
        })
        .catch((error) => {})
    },
    //聊天头像右键菜单
    showSendMenu(event, item, type, index, eleClient, eleOffset) {
      this.$emit('shortcutMenuOffEvent', item)
      if (type === 'send') {
        if (item.userId !== -2) {
          this.chatList.item.forEach((item) => {
            item.isShowSendMenu = false
            item.isShowSendHome = false
          })
          item.isShowSendMenu = true
          if (index == this.chatList.item.length - 1) {
            this.handleScrollBottom('4')
          }
        }
      }
      this.surplusPosition(event, 122, eleClient, eleOffset)
    },
    //聊天头像个人主页
    panelShortcutMenuOff() {
      this.chatList.item.forEach((item) => {
        item.isShowSendHome = false
        item.isShowSendMenu = false
      })
    },
    showSendHome(event, type, item, eleClient, eleOffset) {
      this.$emit('shortcutMenuOffEvent', item)
      this.homeInfo = {}
      if (item.userId == -2) {
        this.chatList.item.forEach((item) => {
          item.isShowSendHome = false
          item.isShowSendMenu = false
        })
        return
      }
      if (type === 'send') {
        this.chatList.item.forEach((item) => {
          item.isShowSendHome = false
          item.isShowSendMenu = false
        })
        item.isShowSendHome = true
      }
      this.surplusPosition(event, 236, eleClient, eleOffset)

      var data = [{ userId: item.userId, loginType: 1 }],
        domain = [this.$store.state.DOMAIN],
        path = ['/project/user/userInfo'],
        dataAxios = this.$tools.getDataAxios(this, domain, path, data)
      Promise.all(dataAxios)
        .then((response) => {
          this.$tools.callbackAxios(this, response, (response) => {
            var data = response[0].data
            if (data.code === 200) {
              this.homeInfo = data.data
              let currentElement = event.target
              let height = currentElement.parentElement.querySelector('.dt-home-info').offsetHeight
              this.surplusPosition(event, height, eleClient, eleOffset)
            } else {
              this.$message({
                message: data.message,
                type: 'warning',
                duration: 2000,
                onClose: () => {}
              })
            }
          })
        })
        .catch((error) => {})
    },
    //个人头像计算底部剩余位置
    surplusPosition(event, homeHeight, eleClient, eleOffset) {
      let chatHeight = eleClient.clientHeight
      let offsetTop = this.offset(event.target, 'top', eleOffset)
      let scrollTop = eleClient.scrollTop
      let curElePosition = offsetTop - scrollTop
      let surplusPosition = chatHeight - curElePosition

      if (homeHeight < surplusPosition) {
        this.isCardUp = false
      } else {
        this.isCardUp = true
      }
    },
    //个人头像计算位置
    offset(element, direction, eleOffset) {
      var offsetDir = 'offset' + direction[0].toUpperCase() + direction.substring(1)
      var realNum = element[offsetDir]
      var positionParent = element.offsetParent
      while (positionParent != null && positionParent.className !== eleOffset) {
        realNum += positionParent[offsetDir]
        positionParent = positionParent.offsetParent
      }
      return realNum
    },
    // 点击查看更多
    getMoreChatList() {
      this.lock.isMoreCount = true
      this.loadDirection = 'top'
      this.getAllChatList(this.chatList)
    },
    //查询聊天历史记录
    getAllChatList(chatList, cb) {
      this.isShowLodding = true
      var data = [{ userId: this.uid, groupId: this.query.groupId, privateUserId: '', lastTime: chatList.item[0].createTimeQuery, pageSize: '10' }],
        domain = [this.$store.state.DOMAIN],
        path = ['/project/customGroup/recordList'],
        dataAxios = this.$tools.getDataAxios(this, domain, path, data)
      Promise.all(dataAxios)
        .then((response) => {
          this.$tools.callbackAxios(this, response, (response) => {
            var data = response[0].data
            if (data.code === 200) {
              this.isShowLodding = false
              if (data.data.moreCount > 0) {
                this.isMoreCount = true
              } else {
                this.isMoreCount = false
              }
              data.data.item.forEach((item) => {
                item.message = JSON.parse(item.message)
                if (item.replyCount > 3) {
                  item.isShowMoreCount = true
                } else {
                  item.isShowMoreCount = false
                }
                item.isShowSendMenu = false
                item.isShowSendHome = false
                item.isShowReply = false
                item.replyTxt = ''
                item.replyImgSrc = ''
                if (item.messageType == 6) {
                  item.isPlayer = false
                  item.isShowText = false
                }
              })
              data.data.item.push(...this.chatList.item)
              this.chatList = { ...data.data }
              // this.chatList.unshift(...item)

              if (this.loadDirection === 'top') {
                this.lock.isMoreCount = false
                this.handleScrollTop()
              } else {
                this.handleScrollBottom('5')
              }
              //成功后回调
              if (cb) {
                cb()
              }
            } else if (data.code === 457) {
              this.$emit('changeRules')
            }
          })
        })
        .catch((error) => {})
    },
    // 判断一个对象是否为空
    isEmpty(obj) {
      return Object.keys(obj).length === 0
    },
    //处理链接为可跳转html
    getHttpsText(str) {
      const regex =
        /(\uD83D\uDE03|\u270A|\uD83D\uDE04|\uD83D\uDE01|\uD83D\uDE06|\uD83D\uDE05|\uD83E\uDD23|\uD83D\uDE02|\uD83D\uDE42|\uD83D\uDE09|\uD83D\uDE0A|\uD83D\uDE07|\uD83D\uDE15|\uD83D\uDE1F|\uD83D\uDE2E|\uD83D\uDE32|\uD83E\uDD7A|\uD83D\uDE26|\uD83D\uDE28|\uD83D\uDE2D|\uD83D\uDE31|\uD83D\uDE23|\uD83D\uDE1E|\uD83D\uDE29|\uD83D\uDE24|\uD83D\uDE21|\uD83D\uDE20|\uD83D\uDE0D|\uD83D\uDE18|\uD83D\uDE1C|\uD83E\uDD2A|\uD83E\uDD2D|\uD83E\uDD2B|\uD83E\uDD14|\uD83D\uDE11|\uD83D\uDE2A|\uD83D\uDE37|\uD83E\uDD2E|\uD83E\uDD27|\uD83D\uDE35|\uD83D\uDE0E|\uD83D\uDCA9|\uD83E\uDD16|\uD83D\uDE48|\uD83D\uDE49|\uD83D\uDE4A|\uD83D\uDC96|\uD83D\uDC94|\uD83D\uDC8B|\uD83D\uDCAF|\uD83D\uDCA2|\uD83D\uDCA8|\uD83D\uDCA4|\uD83D\uDD90|\uD83D\uDC4C|\uD83E\uDD1F|\uD83E\uDD19|\uD83D\uDC48|\uD83D\uDC49|\uD83D\uDC46|\uD83D\uDC47|\uD83D\uDC4D|\uD83D\uDC4F|\uD83D\uDE4C|\uD83E\uDD1D|\uD83D\uDE4F|\uD83D\uDC44|\uD83C\uDF49|\uD83E\uDDC0|\uD83C\uDF54|\uD83C\uDF5A|\uD83C\uDF75|\uD83C\uDF7A|\uD83C\uDF7B|\uD83E\uDD42)/g

      str = str.replace(regex, '<em style="font-size:20px">$1</em>')
      var regHttp = /http(s)?:\/\/|(?<!http(s)?:\/\/)www/gi, //切割http(s)、www字符串加上空格
        regHttpUrl = /(https?:\/\/)?(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&//=]*)/gi, //匹配url加上标签
        regNumberDot = /^[0-9\.]+$/, //纯数字和点
        regSpace = /\s(?=<a class)/gi, //去掉a标签空格
        strArray = null
      str = str.replace(regHttp, ($1) => {
        return ' ' + $1
      })
      strArray = str.split(' ')
      strArray = strArray.map((item) => {
        var str = item.replace(regHttpUrl, ($1) => {
          if (regNumberDot.test($1)) {
            //排除纯数字和点
            return $1
          } else {
            var url = $1.includes('http://') || $1.includes('https://') ? $1 : 'https://' + $1
            return '<a class="dt-chat-content-target-link" href="javascript:void(0);" data-url="' + url + '">' + $1 + '</a>'
          }
        })
        return str
      })
      return strArray.join(' ')
    },
    //跳转外链
    goHttpsLink(e) {
      if (e.target.className === 'dt-chat-content-target-link') {
        if (e.target.dataset.url.includes('ccccdt')) {
          this.$confirm('您即将离开本站，访问中交数科平台，是否继续?', '提示', {
            confirmButtonText: '确定',
            cancelButtonText: '取消',
            cancelButtonClass: 'dt-button-cancle is-plain',
            type: 'warning',
            customClass: 'dt-chat-content-link-confirm'
          })
            .then(() => {
              window.open(e.target.dataset.url)
            })
            .catch(() => {})
        } else {
          this.$confirm('您即将离开本站，访问的链接打开第三方来源网站，可能存在风险，是否继续?', '提示', {
            confirmButtonText: '确定',
            cancelButtonText: '取消',
            cancelButtonClass: 'dt-button-cancle is-plain',
            // iconClass: '',
            type: 'warning',
            customClass: 'dt-chat-content-link-confirm'
          })
            .then(() => {
              window.open(e.target.dataset.url)
            })
            .catch(() => {})
        }
      }
    },
    // 生成时间戳函数
    generateTimestamp() {
      return new Date().getTime()
    },
    // 滚动到顶部
    handleScrollTop() {
      this.$nextTick(() => {
        let scrollElem = this.$refs.scrollChat
        if (scrollElem) {
          scrollElem.scrollTo({ top: 0, behavior: 'smooth' })
        }
      })
    },
    // 滚动到底部
    handleScrollBottom(type) {
      this.$nextTick(() => {
        let scrollElem = this.$refs.scrollChat
        if (scrollElem) {
          scrollElem.scrollTo({ top: scrollElem.scrollHeight, behavior: 'smooth' })
        }
      })
    },
    // 查看回执消息卡片详细信息
    showReceiptCard(item) {
      this.receiptShow = true
      this.getReceiptDetail(item)
    },
    // 获取回执消息卡片详细信息
    getReceiptDetail(item) {
      var data = [
          {
            recordId: item.recordId,
            userId: this.uid
          }
        ],
        domain = [this.$store.state.DOMAIN],
        path = ['/project/customGroup/getReceiptDetail'],
        dataAxios = this.$tools.getDataAxios(this, domain, path, data)
      Promise.all(dataAxios)
        .then((response) => {
          this.$tools.callbackAxios(this, response, (response) => {
            var data = response[0].data
            if (data.code === 200) {
              var joinUserName = data.data.joinUsers.map((item) => item.userName).join('、')
              data.data.joinUserName = joinUserName
              this.receiptInfo = data.data
              if (this.receiptInfo.isCreator == 1) {
                this.receiptWidth = '1040px'
              } else {
                this.receiptWidth = '680px'
              }
            }
          })
        })
        .catch((error) => {})
    },
    // 下载回执消息附件
    downReceiptFile(item) {
      var data = [
          {
            recordId: this.receiptInfo.chatRecordId,
            userId: this.uid,
            fileId: item.id
          }
        ],
        domain = [this.$store.state.DOMAIN],
        path = ['/project/customGroup/receiptDownload'],
        dataAxios = this.$tools.getDataAxios(this, domain, path, data)
      Promise.all(dataAxios)
        .then((response) => {
          this.$tools.callbackAxios(this, response, (response) => {
            var data = response[0].data
            if (data.code === 200) {
            }
          })
        })
        .catch((error) => {})

      var URL = this.$tools.getStsFileUrl(this.$store.state.uid, item.fileUrl)
      if (window.electron) {
        window.electron.ipcRenderer.send('electron:downLoad', URL)
      } else {
        this.downloadFile(URL, item.fileName)
      }
    },
    downloadFile(url, filename, mimeType) {
      // 如果是URL，直接创建a标签下载
      // 检查是否为同源URL
      if (new URL(url).origin !== window.location.origin) {
        // 对于非同源URL，使用window.open在新标签页中打开链接
        window.open(url, '_blank')
      } else {
        // 对于同源URL，可以创建一个临时的<a>元素并模拟点击
        const a = document.createElement('a')
        a.href = url
        a.download = filename
        document.body.appendChild(a)
        a.click()
        document.body.removeChild(a)
      }
    },
    // 回执消息标签页点击
    handleClick(tab, event) {},
    // 确认回执消息按钮点击
    sureReceipt(item, type) {
      if (type == '3') {
        var data = [
          {
            recordId: item.chatRecordId,
            userId: this.uid
          }
        ]
      } else {
        var data = [
          {
            recordId: item.recordId,
            userId: this.uid
          }
        ]
      }

      var domain = [this.$store.state.DOMAIN],
        path = ['/project/customGroup/confirmReceipt'],
        dataAxios = this.$tools.getDataAxios(this, domain, path, data)
      Promise.all(dataAxios)
        .then((response) => {
          this.$tools.callbackAxios(this, response, (response) => {
            var data = response[0].data
            if (data.code === 200) {
              this.$message.success(data.message)
              if (type == '1') {
                item.singleReceiptState = 1
              } else if (type == '2') {
                item.receiptButtonState = 2
              } else {
                item.receiptButtonState = 2
              }
            } else {
              this.$message.warning(data.message)
              if (type == '2') {
                item.receiptButtonState = 3
              } else if (type == '3') {
                item.receiptButtonState = 3
                var currentItem = this.chatList.item.find((currentItem) => currentItem.recordId == item.chatRecordId)
                currentItem.receiptButtonState = 3
              }
            }
          })
        })
        .catch((error) => {})
    },

    // 回执消息下载记录表格样式
    headerRowStyle() {
      return {
        'font-size': '12px', // 设置表头字体大小
        'background-color': '#fafafa', // 设置表头背景色
        'font-weight': 'bold', // 设置表头字体加粗
        color: '#909399 ' // 设置表头字体颜色
      }
    },
    //      展示讨论本条文本框
    showReply(item, index) {
      console.log('showReply', item, index)
      this.replyLoad[index] = false
      item.replyTxt = ''
      item.isShowReply = !item.isShowReply
      if (index == this.chatList.item.length - 1) {
        this.handleScrollBottom('6')
      }
    },
    //  关闭/开启评论
    closeReply(item) {
      item.isShowReply = false
      if (item.originalId) {
        var currentItem = this.chatList.item.find((currentItem) => currentItem.recordId == item.originalId)
        if (currentItem && currentItem.disableComment == 0) {
          currentItem.disableComment = 1
        } else if (currentItem && currentItem.disableComment == 1) {
          currentItem.disableComment = 0
        }
      } else {
        var currentItem = this.chatList.item.find((currentItem) => currentItem.originalId == item.recordId)
        if (currentItem && currentItem.disableComment == 0) {
          currentItem.disableComment = 1
        } else if (currentItem && currentItem.disableComment == 1) {
          currentItem.disableComment = 0
        }
      }
      if (item.disableComment == 0) {
        item.disableComment = 1
      } else {
        item.disableComment = 0
      }
      var data = [{ disableComment: item.disableComment, recordId: item.recordId, userId: this.uid }],
        domain = [this.$store.state.DOMAIN],
        path = ['/project/customGroup/disableComment'],
        dataAxios = this.$tools.getDataAxios(this, domain, path, data)
      Promise.all(dataAxios)
        .then((response) => {
          this.$tools.callbackAxios(this, response, (response) => {
            var data = response[0].data
            if (data.code === 200) {
              this.$message({
                message: data.message,
                type: 'success',
                duration: 2000,
                onClose: () => {}
              })
            } else {
              this.$message({
                message: data.message,
                type: 'warning',
                duration: 2000,
                onClose: () => {}
              })
            }
          })
        })
        .catch((error) => {})
    },
    // 删除消息
    delRecord(item, index) {
      var data = [{ recordId: item.recordId, userId: this.uid }],
        domain = [this.$store.state.DOMAIN],
        path = ['/project/customGroup/deleteChatRecord'],
        dataAxios = this.$tools.getDataAxios(this, domain, path, data)
      Promise.all(dataAxios)
        .then((response) => {
          this.$tools.callbackAxios(this, response, (response) => {
            var data = response[0].data
            if (data.code === 200) {
              this.chatList.item.splice(index, 1)
              if (item.originalId) {
                var currentIndex = this.chatList.item.findIndex((currentItem) => currentItem.recordId == item.originalId)
                if (currentIndex > 0) {
                  this.chatList.item.splice(currentIndex, 1)
                }
              } else {
                var currentIndex = this.chatList.item.findIndex((currentItem) => currentItem.originalId == item.recordId)
                if (currentIndex > 0) {
                  this.chatList.item.splice(currentIndex, 1)
                }
              }
              this.$message({
                message: data.message,
                type: 'success',
                duration: 2000,
                onClose: () => {}
              })
            } else {
              this.$message({
                message: data.message,
                type: 'warning',
                duration: 2000,
                onClose: () => {}
              })
            }
          })
        })
        .catch((error) => {})
    },
    // 镜像消息返回原消息
    goBack(searchItem, index, type) {
      if (type == '2') {
        this.$refs[searchItem.id][0].scrollIntoView({ behavior: 'smooth', block: 'end' })
        this.flicker(searchItem, index, type)
      } else if (type == '3') {
        this.loadDirection = 'top'
        var index = this.chatList.item.findIndex((item) => item.recordId == searchItem.recordId)
        if (index !== -1) {
          this.$refs[searchItem.recordId][0].scrollIntoView({ behavior: 'smooth', block: 'end' })
          this.flicker(searchItem, index, type)
        } else {
          this.jumpRecord(searchItem, type)
        }
      } else {
        var index = this.chatList.item.findIndex((item) => item.recordId == searchItem.originalId)
        if (index !== -1) {
          this.$refs[searchItem.originalId][0].scrollIntoView({ behavior: 'smooth', block: 'end' })
          this.flicker(searchItem, index, type)
        } else {
          this.jumpRecord(searchItem)
        }
      }
    },
    // 跳转之后的消息闪烁效果
    // flicker(searchItem, index, type) {
    //   if (type == '2') {
    //     const element = this.$refs[searchItem.id][0]
    //     element.classList.remove('flashing')
    //     element.removeEventListener('animationend', this.stopBlinking)
    //     // 添加flashing类来启动动画
    //     element.classList.add('flashing')
    //     // 使用匿名函数来绑定this和index
    //     element.addEventListener('animationend', () => this.stopBlinking(searchItem, index, type))
    //   } else if (type == '3') {
    //     const element = this.$refs[searchItem.recordId][0]
    //     element.classList.remove('flashing')
    //     element.removeEventListener('animationend', this.stopBlinking)
    //     // 添加flashing类来启动动画
    //     element.classList.add('flashing')
    //     // 使用匿名函数来绑定this和index
    //     element.addEventListener('animationend', () => this.stopBlinking(searchItem, index, type))
    //   } else {
    //     const element = this.$refs[searchItem.originalId][0]
    //     // 确保在添加新动画之前移除旧的事件监听器
    //     element.classList.remove('flashing')
    //     element.removeEventListener('animationend', this.stopBlinking)

    //     // 添加flashing类来启动动画
    //     element.classList.add('flashing')
    //     // 使用匿名函数来绑定this和index
    //     element.addEventListener('animationend', () => this.stopBlinking(searchItem, index, type))
    //   }
    // },
    // 跳转之后的消息闪烁效果
    flicker(searchItem, index, type) {
      let element
      if (type === '2') {
        element = this.$refs[searchItem.id][0]
      } else if (type === '3') {
        element = this.$refs[searchItem.recordId][0]
      } else {
        element = this.$refs[searchItem.originalId][0]
      }
      // 假设this.stopBlinking是已经定义好的用于停止闪烁的函数
      this.handleElementAnimation(element, searchItem, index, type, this.stopBlinking)
    },
    // 提取的函数，用于处理单个元素的动画相关操作
    handleElementAnimation(element, searchItem, index, type, stopBlinking) {
      this.observeChildInParent(this.$refs.scrollChat, element, searchItem, index, type, stopBlinking)
      // element.classList.remove('flashing')
      // element.removeEventListener('animationend', stopBlinking)
      // // 添加flashing类来启动动画
      // element.classList.add('flashing')
      // // 使用匿名函数来绑定this和相关参数
      // element.addEventListener('animationend', () => stopBlinking(searchItem, index, type))
    },
    observeChildInParent(parent, element, searchItem, index, type, stopBlinking) {
      let observer = new IntersectionObserver(
        (entries) => {
          entries.forEach((entry) => {
            if (entry.isIntersecting) {
              element.classList.remove('flashing')
              element.removeEventListener('animationend', stopBlinking)
              // 添加flashing类来启动动画
              element.classList.add('flashing')
              // 使用匿名函数来绑定this和相关参数
              element.addEventListener('animationend', () => stopBlinking(searchItem, index, type))
              observer.unobserve(element)
            } else {
              // 移除动画类（如果需要）
              element.classList.remove('flashing')
            }
          })
        },
        {
          root: parent // 设置父元素为参照
        }
      )
      observer.observe(element)
    },
    stopBlinking(searchItem, index, type) {
      // 动画结束后移除flashing类
      if (type == '2') {
        var element = this.$refs[searchItem.id] && Array.isArray(this.$refs[searchItem.id]) && this.$refs[searchItem.id][0]
      } else if (type == '3') {
        var element = this.$refs[searchItem.recordId] && Array.isArray(this.$refs[searchItem.recordId]) && this.$refs[searchItem.recordId][0]
      } else {
        var element = this.$refs[searchItem.originalId] && Array.isArray(this.$refs[searchItem.originalId]) && this.$refs[searchItem.originalId][0]
      }
      element.classList.remove('flashing')
      // 移除animationend事件监听器
      element.removeEventListener('animationend', this.stopBlinking)
    },
    //查询聊天记录位置
    jumpRecord(record, type) {
      if (type == '2' || type == '3') {
        var data = [
          {
            groupId: this.query.groupId,
            userId: this.uid,
            // privateUserId: record.privateUserId || 0,
            pageSize: 10,
            recordId: record.id || record.recordId
          }
        ]
      } else {
        if (record.originalId) {
          var data = [
            {
              groupId: this.query.groupId,
              userId: this.uid,
              // privateUserId: record.privateUserId,
              pageSize: 10,
              recordId: record.originalId
            }
          ]
        } else {
          var data = [
            {
              groupId: this.query.groupId,
              userId: this.uid,
              // privateUserId: record.privateUserId,
              pageSize: 10,
              record_id: record.recordId
            }
          ]
        }
      }

      var domain = [this.$store.state.DOMAIN],
        path = ['/project/customGroup/recordList'],
        dataAxios = this.$tools.getDataAxios(this, domain, path, data)
      Promise.all(dataAxios)
        .then((response) => {
          this.$tools.callbackAxios(this, response, (response) => {
            var data = response[0].data
            if (data.code === 200) {
              if (data.data.moreCount > 0) {
                this.isMoreCount = true
              } else {
                this.isMoreCount = false
              }
              data.data.item.forEach((item) => {
                item.message = JSON.parse(item.message)
                if (item.replyCount > 3) {
                  item.isShowMoreCount = true
                } else {
                  item.isShowMoreCount = false
                }
                item.isShowSendMenu = false
                item.isShowSendHome = false
                item.isShowReply = false
                item.replyTxt = ''
                item.replyImgSrc = ''
                if (item.messageType == 6) {
                  item.isPlayer = false
                  item.isShowText = false
                }
              })
              this.chatList = { ...data.data }
              if (record.originalId) {
                var index = this.chatList.item.findIndex((item) => item.recordId === record.originalId)
              } else {
                var index = this.chatList.item.findIndex((item) => item.recordId === record.recordId)
              }
              this.$nextTick(() => {
                if (type == '2') {
                  this.$refs[record.id][0].scrollIntoView({ behavior: 'smooth', block: 'end' })
                  this.goBack(record, index, type)
                } else if (type == '3') {
                  this.$refs[record.recordId][0].scrollIntoView({ behavior: 'smooth', block: 'end' })
                  this.goBack(record, index, type)
                } else {
                  this.$refs[record.originalId][0].scrollIntoView({ behavior: 'smooth', block: 'end' })
                  this.goBack(record, index)
                }
              })
              if (data.data.moreCountNew > 0) {
                this.recursionState = true
                this.afterRecording(data.data.nextTime)
              }
              // this.chatList = data.data.item
              // this.handleScrollTop()
            } else if (data.code === 452) {
              location.reload()
            }
          })
        })
        .catch((error) => {})
    },
    // 查询聊天记录之后的消息
    afterRecording(nextTime) {
      var data = [
          {
            groupId: this.query.groupId,
            userId: this.uid,
            pageSize: 10,
            nextTime: nextTime
          }
        ],
        domain = [this.$store.state.DOMAIN],
        path = ['/project/customGroup/recordList'],
        dataAxios = this.$tools.getDataAxios(this, domain, path, data)
      Promise.all(dataAxios)
        .then((response) => {
          this.$tools.callbackAxios(this, response, (response) => {
            var data = response[0].data
            if (data.code === 200) {
              if (data.data.moreCountNew > 0) {
                if (data.data.moreCount > 0) {
                  this.isMoreCount = true
                } else {
                  this.isMoreCount = false
                }
                data.data.item.forEach((item) => {
                  item.message = JSON.parse(item.message)
                  if (item.replyCount > 3) {
                    item.isShowMoreCount = true
                  } else {
                    item.isShowMoreCount = false
                  }
                  item.isShowSendMenu = false
                  item.isShowSendHome = false
                  item.isShowReply = false
                  item.replyTxt = ''
                  item.replyImgSrc = ''
                  if (item.messageType == 6) {
                    item.isPlayer = false
                    item.isShowText = false
                  }
                })
                data.data.item.unshift(...this.chatList.item)
                this.chatList = { ...data.data }
                this.afterRecording(data.data.nextTime)
              } else {
                if (data.data.moreCount > 0) {
                  this.isMoreCount = true
                } else {
                  this.isMoreCount = false
                }
                data.data.item.forEach((item) => {
                  item.message = JSON.parse(item.message)
                  if (item.replyCount > 3) {
                    item.isShowMoreCount = true
                  } else {
                    item.isShowMoreCount = false
                  }
                  item.isShowSendMenu = false
                  item.isShowSendHome = false
                  item.isShowReply = false
                  item.replyTxt = ''
                  item.replyImgSrc = ''
                  if (item.messageType == 6) {
                    item.isPlayer = false
                    item.isShowText = false
                  }
                })
                data.data.item.unshift(...this.chatList.item)
                this.chatList = { ...data.data }
                this.recursionState = false
              }
            } else if (data.code === 452) {
              location.reload()
            } else if (data.code === 457) {
              this.$emit('changeRules')
            }
          })
        })
        .catch((error) => {})
    },
    // 举报
    report(item, items) {
      this.reportCont.replyId = ''
      this.reportIsShow = true
      if (items) {
        console.log(items, 'items')
        this.reportCont.userName = items.userName
        this.reportCont.message = JSON.parse(items.message).message
        this.reportCont.replyId = items.replyId
        this.reportCont.messageType = items.messageType
        this.reportCont.shortMessage = items.shortMessage
      } else {
        this.reportCont.userName = item.userName
        this.reportCont.message = item.message.message
        this.reportCont.messageType = item.message.messageType
        this.reportCont.shortMessage = item.shortMessage
      }
      this.reportCont.groupId = item.groupId
      this.reportCont.recordId = item.recordId
    },
    submitFormReport(formName) {
      this.$refs[formName].validate((valid) => {
        if (valid) {
          this.lock.report = true
          this.submitReport(formName)
        } else {
          console.log('error submit!!')
          return false
        }
      })
    },
    resetFormReport(formName) {
      this.$refs[formName].resetFields()
      this.reportIsShow = false
    },
    submitReport(formName) {
      var data = [
          {
            userId: this.uid,
            groupId: this.reportCont.groupId,
            recordId: this.reportCont.recordId,
            reportType: this.reportRuleForm.reportType,
            source: 1,
            replyId: this.reportCont.replyId
          }
        ],
        domain = [this.$store.state.DOMAIN],
        path = ['/project/report/reportMsg'],
        dataAxios = this.$tools.getDataAxios(this, domain, path, data)
      Promise.all(dataAxios)
        .then((response) => {
          this.$tools.callbackAxios(this, response, (response) => {
            var data = response[0].data
            if (data.code === 200) {
              this.reportIsShow = false
              this.lock.report = false
              this.$message({
                message: '举报成功',
                type: 'success',
                duration: 2000,
                onClose: () => {
                  this.$refs[formName].resetFields()
                }
              })
            } else {
              this.lock.report = false
              this.$message({
                message: data.message,
                type: 'warning',
                duration: 2000,
                onClose: () => {
                  this.reportIsShow = false
                }
              })
            }
          })
        })
        .catch((error) => {})
    }, //举报结束
    // 评论消息发送图片
    //触发fileinput
    showFileInput(type, item, index) {
      if (this.lock.sendMess) {
        this.$message({
          message: '文件发送中，请稍后',
          type: 'warning',
          duration: 2000,
          onClose: () => {}
        })
        return
      }
      if (item) {
        this.recordItem = item
        this.replyIndex = index
      }
      this.$refs['fileInput' + type].click()
    },
    //fileinput触发change
    fileChage(e, type) {
      var files = e.target.files
      this.testFile(files, type)
    },
    testFile(files, type) {
      // 验证文件类型和大小
      var fileValidationResults = this.validateFiles(files, type)
      // 如果有错误，显示错误信息并返回
      if (fileValidationResults.hasErrors) {
        this.showFileValidationError(fileValidationResults.errorMessages)
        return
      }
      // 定义文件上传的限制
      const limits = {
        img: 9,
        Replyimg: 1,
        file: 1
        // 其他类型不需要限制，所以不在这里定义
      }

      // 检查文件数量限制（仅对已定义的类型）
      if (limits[type] && files.length > limits[type]) {
        this.$message({
          message: `请最多选择${limits[type]}个文件`,
          type: 'warning'
        })
        return
      }
      // 根据文件类型执行不同的操作
      if (type === 'Replyimg') {
        this.replyLoad[this.replyIndex] = true
        this.handleReplyImgUpload(files)
      }
    },
    /**
     * 验证文件类型和大小的方法
     */
    validateFiles(files, type) {
      const tipString = {
        all: '请上传jpg、jpeg、gif、png、txt、pdf、doc、docx、xls、xlsx、ppt、pptx、rar、zip文件!',
        img: '请上传jpg、jpeg、gif、png文件!',
        file: '请上传txt、pdf、doc、docx、xls、xlsx、ppt、pptx、rar、zip文件!',
        Replyimg: '请上传jpg、jpeg、gif、png文件!'
      }
      const errorMessages = []

      for (const file of files) {
        const suffName = this.$tools.getFileSuffix(file.name)
        if (!this.$tools.isFileTypeOk(suffName, type)) {
          errorMessages.push(tipString[type])
        } else if (!this.$tools.isFileLess(file.size, 500)) {
          errorMessages.push('请上传小于500M的文件!')
        }
      }

      return {
        hasErrors: errorMessages.length > 0,
        errorMessages
      }
    },
    /**
     *  显示文件错误提示
     */
    showFileValidationError(errorMessages) {
      errorMessages.forEach((message) => {
        this.$message({
          message,
          type: 'warning'
        })
      })
    },
    /**
     * 上传回复评论图片并添加水印
     */
    handleReplyImgUpload(files) {
      var file = files[0],
        fileNames = [],
        fileSrcs = []
      this.$tools.getStsClient(this, file, (state, client, bucketName, file) => {
        if (state) {
          // 添加水印
          this.watermarkImage(file, this.dataURLtoFile)
            .then(({ dataURL, img_width, img_height }) => {
              // 调用uploadFile函数上传加水印的图片
              this.uploadFile(client, bucketName, dataURL, (key) => {
                var url = 'https://www.ccccdt.com/ccccdt/' + key
                fileNames.push(file.name)
                fileSrcs.push(url)
                this.recordItem.replyTxt = fileNames.join('|')
                this.recordItem.replyImgSrc = fileSrcs.join('|')
                this.recordItem.imgWidth = img_width
                this.recordItem.imgHeight = img_height
                this.sendReplyInfo(this.recordItem, this.replyIndex, '3', file)
              })
            })
            .catch((error) => {
              console.error('Error adding watermark:', error)
              // 处理添加水印的错误
            })
        }
      })
    },
    // 图片添加水印
    watermarkImage(file, dataURLtoFile) {
      var currenDate = this.$tools.getDateFormatString('ymdhms')
      return new Promise((resolve, reject) => {
        const reader = new FileReader()
        reader.onload = function (e) {
          const img = new Image()
          img.onload = function () {
            const canvas = document.createElement('canvas')
            const ctx = canvas.getContext('2d')
            // 确保画布尺寸与图片尺寸一致
            canvas.width = img.width
            canvas.height = img.height
            // 绘制原始图片
            ctx.drawImage(img, 0, 0, img.width, img.height, 0, 0, canvas.width, canvas.height)
            // 根据图片尺寸调整水印文字大小和位置
            var fontSize = Math.round(canvas.width / 30) // 字体大小根据图片宽度调整
            var watermarkX = canvas.width * 0.98 // 文字距离右侧边缘2%
            var watermarkY = canvas.height * 0.98 // 文字距离底部边缘2%
            // 添加水印文字
            // 设置文本样式和阴影

            ctx.textAlign = 'right'
            ctx.textBaseline = 'bottom'
            ctx.font = `${fontSize}px Microsoft YaHei`
            ctx.shadowOffsetX = 0
            ctx.shadowOffsetY = 0
            ctx.shadowBlur = 5
            ctx.shadowColor = 'rgb(0, 0, 0)'
            // 绘制矩形
            ctx.fillStyle = 'rgb(255, 255, 255)' // 矩形的填充颜色
            // 绘制带阴影的文本，右下对齐
            ctx.fillText(currenDate, watermarkX, watermarkY - (fontSize + 10))
            ctx.fillText('数科帮', watermarkX, watermarkY)
            // 使用 dataURLtoFile 方法将 DataURL 转换为 File 对象
            // 使用与原始图片相同的MIME类型将canvas内容转换为DataURL
            var mimeType = file.type
            var quality = 0.8 // 设置您想要的压缩质量，0到1之间
            var dataURL = canvas.toDataURL(mimeType, quality)
            var new_dataURL = dataURLtoFile(dataURL, file.name)
            resolve({ dataURL: new_dataURL, img_width: img.width, img_height: img.height })
          }
          img.src = e.target.result
        }
        reader.onerror = function () {
          reject(reader.error)
        }
        reader.readAsDataURL(file)
      })
    },
    //将DataURL转换为File
    dataURLtoFile(dataurl, filename) {
      var arr = dataurl.split(','),
        mime = arr[0].match(/:(.*?);/)[1],
        bstr = atob(arr[1]),
        n = bstr.length,
        u8arr = new Uint8Array(n)
      while (n--) {
        u8arr[n] = bstr.charCodeAt(n)
      }
      return new File([u8arr], filename, { type: mime })
    },
    // 发送回复聊天信息
    sendReplyInfo(item, index, messageType, file) {
      this.replyLoad[index] = true
      var dangerReg = /[\<\>]/
      if (dangerReg.test(item.replyTxt)) {
        this.$message({
          message: '发送内容包含危险字符，请重新编辑!',
          type: 'warning'
        })
        return
      }
      if (messageType === '2') {
        var messageArr = item.replyTxt.split('\n')
        var messageObj = []
        messageArr.forEach((item, index) => {
          messageObj.push({
            content: item.trim(),
            bold: '',
            wrap: 'true',
            color: '',
            sort: index + 1 + ''
          })
        })
        var messageJson = {
          messageType: messageType,
          message: messageObj
        }
      }
      if (messageType === '3') {
        if (file) {
          var messageJson = {
            messageType: messageType,
            message: []
          }
          messageJson.message.push({
            fileName: file.name,
            fileUrl: item.replyImgSrc,
            fileSize: file.size,
            fileSuffix: file.name.substring(file.name.lastIndexOf('.') + 1),
            sort: 1 + '',
            imgWidth: item.imgWidth,
            imgHeight: item.imgHeight
          })
        } else {
          return
        }
      }
      var data = [
          {
            message: JSON.stringify(messageJson),
            messageType: messageType,
            recordId: item.recordId,
            userId: this.uid
          }
        ],
        domain = [this.$store.state.DOMAIN],
        path = ['/project/customGroup/sendReply'],
        dataAxios = this.$tools.getDataAxios(this, domain, path, data)
      Promise.all(dataAxios)
        .then((response) => {
          this.$tools.callbackAxios(this, response, (response) => {
            var data = response[0].data
            if (data.code === 200) {
              this.recordItem = null
              item.replyTxt = ''
              item.replyImgSrc = ''
              item.imgHeight = null
              item.imgWidth = null
              this.$refs.fileInputReplyimg.value = ''
              this.replyLoad[index] = false
              this.showReply(item)
            } else if (data.code === 453) {
              item.disableComment = 1
              item.isShowReply = false
              this.replyLoad[index] = false
              this.$message({
                message: '消息已关闭评论',
                type: 'warning',
                duration: 2000,
                onClose: () => {}
              })
            } else if (data.code === 457) {
              this.$emit('changeRules')
            } else {
              this.replyLoad[index] = false
              this.showReply(item)
              this.$message({
                message: data.message,
                type: 'warning',
                duration: 2000,
                onClose: () => {}
              })
            }
          })
        })
        .catch((error) => {})
    },
    //上传文件、成功和进度回调
    uploadFile(client, bucketName, file, cbSucess, cbProgress) {
      var time = new Date().getTime() + '',
        key = time.split('').reverse().join('') + this.$tools.getRandomFileName(file),
        params = {
          Body: file, //成功和进度回调
          Bucket: bucketName,
          Key: key,
          ContentDisposition: `attachment; filename="${encodeURIComponent(file.name)}"`
        }
      client
        .putObject(params, (err, data) => {
          if (err) {
          } else {
            cbSucess(key)
          }
        })
        .on('httpUploadProgress', (progress) => {
          if (cbProgress) {
            cbProgress(progress)
          }
        })
    },
    // 回复评论中查看图片
    showReplyImg(event) {
      // console.log(event.target.querySelector('.el-image__preview'))
      if (event.target.querySelector('.el-image__preview')) {
        event.target.querySelector('.el-image__preview').click()
      }
      // var messageArr = JSON.parse(message)
      // this.replyImgSrc = this.$tools.getStsFileUrl(this.secretUid, messageArr.message[0].fileUrl)
      // this.isShowReplyImg = true
    },
    //获取回复列表信息
    getReplyList(item) {
      var data = [{ recordId: item.recordId, userId: this.uid, page: 1, pageSize: 100000 }],
        domain = [this.$store.state.DOMAIN],
        path = ['/project/customGroup/replyList'],
        dataAxios = this.$tools.getDataAxios(this, domain, path, data)
      Promise.all(dataAxios)
        .then((response) => {
          this.$tools.callbackAxios(this, response, (response) => {
            var data = response[0].data
            if (data.code === 200) {
              item.isShowMoreCount = false
              item.reply = data.data.items
            }
          })
        })
        .catch((error) => {})
    },
    // 收起评论框
    foldReplyList(item) {
      // console.log(item)
      item.isShowMoreCount = !item.isShowMoreCount
      item.reply = item.reply.slice(0, 3)
    },
    // 通知input组件艾特消息
    //  <li @click="appendAtuser('panel',item.userId,item.userName)">
    appendAtuser(type, userId, userName) {
      this.$emit('appendAtuser', type, userId, userName)
    },
    // 通知input组件私聊消息
    appendPrivate(type, userId, userName) {
      this.$emit('appendPrivate', type, userId, userName)
    },
    // 通知input组件单一回执消息
    appendReceipt(type, userId, userName) {
      this.$emit('appendReceipt', type, userId, userName)
    },
    // 单一回执消息文件的时候前面的图片
    currFilecon(file) {
      return '/skb/img/chat/ic_' + file.fileSuffix + '.png'
    },
    downFile(item) {
      // if (item.singleReceiptUid == this.uid || item.userId == this.uid) {
      this.downCurrentReceiptFile(item)
      // console.log(item)
      // } else {
      //   this.$message.error('只有本人才能下载')
      // }
    },
    // 下载单一回执消息附件
    downCurrentReceiptFile(item) {
      var URL = this.$tools.getStsFileUrl(this.$store.state.uid, item.message.message[0].fileUrl)
      if (window.electron) {
        window.electron.ipcRenderer.send('electron:downLoad', URL)
      } else {
        this.downloadFile(URL, item.message.message[0].fileName)
      }
    },
    //设置@用户
    setAtmeuser(atUsernames) {
      this.atMeuser = atUsernames
    },
    //清理@用户
    clearAtmeuser() {
      // this.atMeuser = {}
      var index = this.chatList.item.findIndex((item) => item.recordId === this.atMeuser.message[0].id)
      if (index !== -1) {
        this.$nextTick(() => {
          this.$refs[this.atMeuser.message[0].id][0].scrollIntoView({ behavior: 'smooth', block: 'end' })
          this.goBack(this.atMeuser.message[0], index, '2')
          this.atMeuser = {}
        })
      } else {
        this.jumpRecord(this.atMeuser.message[0], '2')
        this.atMeuser = {}
      }
    },
    // 设置私聊我的用户列表
    setPrivateuser(atUsernames) {
      // 私聊我的用户列表
      this.privateUser = atUsernames
    },
    // 清理私聊我的用户列表
    clearPrivateuser() {
      var index = this.chatList.item.findIndex((item) => item.recordId === this.privateUser.message[0].id)
      if (index !== -1) {
        this.$nextTick(() => {
          this.$refs[this.privateUser.message[0].id][0].scrollIntoView({ behavior: 'smooth', block: 'end' })
          this.goBack(this.privateUser.message[0], index, '2')
          this.privateUser = {}
        })
      } else {
        this.jumpRecord(this.privateUser.message[0], '2')
        this.privateUser = {}
      }
    },
    setReplyUser(atUsernames) {
      this.replyUser = atUsernames
    },
    clearReplyUser() {
      var index = this.chatList.item.findIndex((item) => item.recordId === this.replyUser.message[0].id)
      if (index !== -1) {
        this.$nextTick(() => {
          this.$refs[this.replyUser.message[0].id][0].scrollIntoView({ behavior: 'smooth', block: 'end' })
          this.goBack(this.replyUser.message[0], index, '2')
          this.replyUser = {}
        })
      } else {
        this.jumpRecord(this.replyUser.message[0], '2')
        this.replyUser = {}
      }
    },
    /**
     *
     * @param event
     * 图片加载完成事件并获取宽度
     */
    // onImageLoad(event) {
    //   const img = event.target
    //   const originalWidth = img.naturalWidth || img.width

    //   // 计算对话框的最大宽度，不超过屏幕宽度的一半加上一定的边距
    //   const halfScreenWidth = window.innerWidth / 2
    //   const maxWidth = halfScreenWidth - 40 // 减去边距

    //   // 设置对话框的宽度为图片宽度和最大宽度中的较小值
    //   this.dialogWidth = `${Math.min(originalWidth, maxWidth)}px`
    // },
    //关闭评论中查看图片
    // closeReplyImg() {
    //   this.replyImgSrc = null
    //   this.isShowReplyImg = false
    // },
    //监听socket 新消息事件
    groupMessage(data) {
      this.loadDirection = 'bottom'
      var currentJson = data
      currentJson.message = JSON.parse(currentJson.message)
      if (currentJson.replyCount > 3) {
        currentJson.isShowMoreCount = true
      } else {
        currentJson.isShowMoreCount = false
      }
      currentJson.isShowSendMenu = false
      currentJson.isShowSendHome = false
      currentJson.isShowReply = false
      currentJson.replyTxt = ''
      currentJson.replyImgSrc = ''
      currentJson.isPlayer = false
      currentJson.isShowText = false
      if (currentJson.originalId) {
        var _index = this.chatList.item.findIndex((item) => item.recordId === currentJson.recordId)
        if (_index == -1) {
          this.chatList.item.push(currentJson)
        } else {
          if (currentJson.replaceRecord == 0) {
            this.chatList.item.splice(_index, 1)
            this.chatList.item.push(currentJson)
          } else {
            if (this.chatList.item[_index].isShowText) {
              this.chatList.item[_index].isPlayed = currentJson.isPlayed
            } else {
              this.chatList.item.splice(_index, 1, currentJson)
            }
          }
        }
      } else {
        if (currentJson.replaceRecord == 0) {
          if (this.chatList && this.chatList.item) {
            this.chatList.item.push(currentJson)
          }
        } else {
          var _index = this.chatList.item.findIndex((item) => item.recordId === currentJson.recordId)
          if (_index !== -1) {
            if (this.chatList.item[_index].isShowText) {
              this.chatList.item[_index].isPlayed = currentJson.isPlayed
            } else {
              this.chatList.item.splice(_index, 1, currentJson)
            }
          }
        }
      }
      if (currentJson.userId == this.uid) {
        if (currentJson.replaceRecord == 0) {
          this.handleScrollBottom('7')
        }
      } else {
        let scrollElem = this.$refs.scrollChat
        if (scrollElem) {
          // 获取滚动元素的滚动高度和视口高度
          const scrollHeight = scrollElem.scrollHeight
          const clientHeight = scrollElem.clientHeight
          const scrollTop = scrollElem.scrollTop
          setTimeout(() => {
            // 检查是否已经滚动到底部
            if (scrollTop + clientHeight >= scrollHeight - 1) {
              // 如果已经在底部，需要滚动
              this.handleScrollBottom('8')
            } else {
              // 如果不在底部，则不需要滚动
              // scrollElem.scrollTo({ top: scrollHeight, behavior: 'smooth' })
            }
          }, 300) // 假设滚动动画需要300ms
        }
      }
    },
    //监听socket 评论回复事件
    messageReply(data) {
      var currentItem = this.chatList.item.find((item) => item.recordId === data.chatRecordId)
      if (currentItem) {
        currentItem.replyCount++
        currentItem.reply.unshift(data)

        let scrollElem = this.$refs.scrollChat
        if (scrollElem) {
          // 获取滚动元素的滚动高度和视口高度
          const scrollHeight = scrollElem.scrollHeight
          const clientHeight = scrollElem.clientHeight
          const scrollTop = scrollElem.scrollTop

          // 检查是否已经滚动到底部
          if (scrollTop + clientHeight === scrollHeight) {
            // 如果已经在底部，需要滚动
            this.handleScrollBottom('9')
          } else {
            // 如果不在底部，则不需要滚动
            // scrollElem.scrollTo({ top: scrollHeight, behavior: 'smooth' })
          }
        }
      }
    },
    // 监听socket 删除消息  开启关闭评论 事件
    messageOperator(data) {
      if (data.type == 1) {
        var currentIndex = this.chatList.item.findIndex((currentItem) => currentItem.recordId == data.recordId)
        if (currentIndex > 0) {
          this.chatList.item.splice(currentIndex, 1)
        }
      } else if (data.type == 2) {
        var currentItem = this.chatList.item.find((currentItem) => currentItem.recordId == data.recordId)
        if (currentItem && currentItem.disableComment == 0) {
          currentItem.disableComment = 1
        }
      } else {
        var currentItem = this.chatList.item.find((currentItem) => currentItem.recordId == data.recordId)
        if (currentItem && currentItem.disableComment == 1) {
          currentItem.disableComment = 0
        }
      }
    },
    /********************新消息通知********************/
    // 监听评论回复

    // 评论我的用户列表
    // replyUser: {}
    // //设置@用户文本
    // setAtmeuserText() {
    //   var groupId = this.groupId + '_',
    //     atMeuser = this.$cookies.get('atmeuser') ? this.$cookies.get('atmeuser') : {}
    //   this.atmeUserText = ''
    //   if (atMeuser[groupId]) {
    //     if (atMeuser[groupId].length === 1) {
    //       this.atmeUserText = atMeuser[groupId][0].username + '@你'
    //     } else if (atMeuser[groupId].length > 1) {
    //       this.atmeUserText = atMeuser[groupId].length + '人@你'
    //     }
    //   }
    // }
    // /** 语音消息相关功能 */
    /**
     * 计算语音消息的宽度，根据音频时长计算
     */
    voiceMessageWidth(duration) {
      // 最小宽度和最大宽度
      let baseWidth = 50 // 最小宽度
      let maxWidth = 280 // 最大宽度

      // 可增加的宽度范围（最大宽度减去基础宽度）
      let widthRange = maxWidth - baseWidth

      // 假设音频最大时长为60秒，计算每秒增加的宽度
      let widthPerSecond = widthRange / 60

      // 根据音频时长计算宽度增加量
      let widthIncrease = duration * widthPerSecond

      // 计算最终宽度，并确保它在最小和最大宽度之间
      let calculatedWidth = baseWidth + widthIncrease
      // console.log(Math.min(Math.max(calculatedWidth, baseWidth), maxWidth))
      return `${Math.min(Math.max(calculatedWidth, baseWidth), maxWidth)}px`
    },
    /**
     * 开启动画
     */
    waveAnimation(currentTarget, event, IsAnimation) {
      // 检查事件的目标是否是voice-message元素或其子元素
      if (event.target.classList.contains('voice-message') || event.target.closest('.voice-message') !== null) {
        const voiceMessageElement = currentTarget
        const iconElement = voiceMessageElement.querySelector('.icon')
        // 获取所有'icon'类名的元素
        const allIconElements = document.querySelectorAll('.icon')
        // 停止所有'icon'元素的动画，并添加暂停类名
        allIconElements.forEach((icon) => {
          icon.classList.remove('animation')
          icon.classList.add('paused')
        })
        // 检查是否已经暂停 if (iconElement.classList.contains('animation'))
        if (!IsAnimation) {
          // 移除暂停类名，并重新开始动画
          iconElement.classList.add('paused')
          iconElement.classList.remove('animation')
        } else {
          // 添加暂停类名，并保持最后一帧的样式
          iconElement.classList.remove('paused')
          iconElement.classList.add('animation')
        }
      }
    },
    /**
     * 播放/暂停语音函数
     */
    async playOrPauseVoice(event, item) {
      this.stopAllVoices(item)
      item.isPlayer = !item.isPlayer
      var currentTarget = event.currentTarget
      this.waveAnimation(currentTarget, event, item.isPlayer)
      if (item.isPlayed == 0) {
        this.setMessagePlayed(item)
      }
      var self = this
      if (item.isPlayer) {
        if (item.amr) {
          item.amr.play()
        } else {
          var url = await this.getSignedUrlForItem(item)
          var amr = new BenzAMRRecorder()
          item.amr = amr
          item.amr
            .initWithUrl(url)
            .then(() => {
              if (item.amr.isInit()) {
                // 添加 onEnded 事件监听器
                item.amr.onStop(function () {
                  // 这里可以放置当语音播放结束时的逻辑
                  item.isPlayer = false // 重置播放状态
                  self.waveAnimation(currentTarget, event, item.isPlayer) // 重置动画
                })
                item.amr.play()
              }
            })
            .catch((error) => {
              console.log(error)
            })
        }
      } else {
        item.amr.stop()
      }
    },
    // 生成天翼云临时链接函数
    async getSignedUrlForItem(item) {
      return new Promise((resolve, reject) => {
        const filename = item.message.message[0].fileUrl.split('/').pop()
        this.$tools.getStsClient(this, null, (state, client, bucketName) => {
          if (state) {
            const params = {
              Bucket: bucketName,
              Key: filename
            }
            var url = client.getSignedUrl('getObject', params)
            if (url) {
              resolve(url)
            } else {
              reject('Failed to get signed URL')
            }
          } else {
            reject(new Error('Failed to get STS client'))
          }
        })
      })
        .then((signedUrl) => {
          // 这里处理成功获取签名 URL 的情况
          return signedUrl
        })
        .catch((error) => {
          // 这里处理错误情况
          console.error('Error getting signed URL:', error)
        })
    },
    // 停止所有语音播放并重置状态的辅助方法
    stopAllVoices(item) {
      this.chatList.item.forEach((chatItem) => {
        if (chatItem.amr && chatItem.recordId != item.recordId) {
          // console.log('停止播放第一次')
          chatItem.amr.stop()
          chatItem.isPlayer = false
        }
      })
    },
    // 是否显示语音文字
    showText(item) {
      item.isShowText = !item.isShowText
      if (this.isLastObject(this.chatList.item, item)) {
        this.$nextTick(() => {
          this.handleScrollBottom('9')
        })
      }
      if (!item.message.message[0].text) {
        var data = [{ recordId: item.recordId, userId: this.uid, type: '2' }],
          domain = [this.$store.state.DOMAIN],
          path = ['/project/v2t/translate'],
          dataAxios = this.$tools.getDataAxios(this, domain, path, data)
        Promise.all(dataAxios)
          .then((response) => {
            this.$tools.callbackAxios(this, response, (response) => {
              var data = response[0].data
              if (data.code === 200) {
                this.$set(item.message.message[0], 'text', data.data)
                if (this.isLastObject(this.chatList.item, item)) {
                  this.$nextTick(() => {
                    this.handleScrollBottom('9')
                  })
                }
              } else {
                this.$message({
                  message: data.message,
                  type: 'warning',
                  duration: 2000,
                  onClose: () => {}
                })
                this.$set(item.message.message[0], 'text', data.message)
                if (this.isLastObject(this.chatList.item, item)) {
                  this.$nextTick(() => {
                    this.handleScrollBottom('9')
                  })
                }
              }
            })
          })
          .catch((error) => {})
      }
    },
    // 设置语音消息已播放
    setMessagePlayed(item) {
      var data = [{ recordId: item.recordId, userId: this.uid }],
        domain = [this.$store.state.DOMAIN],
        path = ['/project/customGroup/setMessagePlayed'],
        dataAxios = this.$tools.getDataAxios(this, domain, path, data)
      Promise.all(dataAxios)
        .then((response) => {
          this.$tools.callbackAxios(this, response, (response) => {
            var data = response[0].data
            if (data.code === 200) {
              item.isPlayed = 1
            }
          })
        })
        .catch((error) => {})
    },
    // 判断是否是最后一个元素
    isLastObject(arr, targetObject) {
      const index = arr.findIndex((obj) => obj.recordId === targetObject.recordId)
      return index === arr.length - 1
    }
  },
  mounted() {
    window.addEventListener('click', (e) => {
      this.selectRecordId = ''
      this.isShowEmoji = false
    })
    this.getChatList()
    //隐藏右键菜单
    $(document).on('click contextmenu', () => {
      if (!this.isEmpty(this.chatList)) {
        this.chatList.item.forEach((item) => {
          item.isShowSendMenu = false
          item.isShowSendHome = false
        })
      }
    })
    var timer = setInterval(() => {
      if (this.$socket) {
        clearInterval(timer)
        this.$socket.emit('joinGroup', 'group-' + this.query.groupId)
        this.$socket.on('group_message', (data) => {
          var _data = JSON.parse(data)
          if (this.query.groupId == _data.groupId) {
            this.groupMessage(_data)
          }
        })
        this.$socket.on('message_prompt', (data) => {
          var _data = JSON.parse(data)
          if (this.query.groupId == _data.groupId) {
            if (_data.type == 1) {
              this.setPrivateuser(_data)
            }
            if (_data.type == 2) {
              this.setAtmeuser(_data)
            }
            if (_data.type == 3) {
              this.setReplyUser(_data)
            }
          }
        })
        this.$socket.on('message_reply', (data) => {
          var _data = JSON.parse(data)
          if (this.query.groupId == _data.groupId) {
            this.messageReply(_data)
          }
        })
        this.$socket.on('message_operator', (data) => {
          var _data = JSON.parse(data)
          if (this.query.groupId == _data.groupId) {
            this.messageOperator(_data)
          }
          // this.messageOperator(_data)
        })
      }
    }, 10)
    if (window.electron) {
      window.electron.ipcRenderer.on('electron:isFocus', (_, args) => {
        // console.log('isFocus===============', args)
        if (args) {
          this.$socket.emit('joinGroup', 'group-' + this.query.groupId)
          this.getChatList()
        } else {
          this.$socket.emit('leaveGroup', 'group-' + this.query.groupId)
        }
      })
    }
  },
  watch: {
    //路由hash变化 加载组件
    $route(to, from) {
      if (to.hash !== from.hash) {
        if (!to.hash.includes('tab=org') && this.query.groupId) {
          this.getChatList()
          this.atMeuser = {}
          this.privateUser = {}
          this.replyUser = {}
          this.receiptShow = false
        }
        // if (to.hash.includes('tab=org')) {
        //   return
        // }
        // if (this.query.groupId) {
        //   this.getChatList()
        //   this.atMeuser = {}
        //   this.privateUser = {}
        //   this.replyUser = {}
        // }
      }
    }
  }
}
</script>
<style scoped>
.dt-talk-panel {
  flex: 1;
  /* padding: 20px 0; */
  overflow: auto;
  border-bottom: 1px solid #e5e5e5;
  text-align: center;
  background-color: #f2f3f5;
  display: flex;
}
.dt-chat-content-more {
  height: 40px;
  line-height: 40px;
  text-align: center;
}
/* 聊天记录每一条的样式 */
.dt-chat-content-list {
  padding: 4px 5px 5px;
  margin: 0 20px;
  text-align: left;
  position: relative;
}
.dt-chat-curr {
  background-color: #f0f5ff;
}
.dt-chat-content-team {
  flex: 1;
  display: flex;
  flex-direction: column;
  overflow: auto;
  position: relative;
}
.dt-chat-content-teamin {
  flex: 1;
  overflow: auto;
  /* border-bottom: 1px solid #e5e5e5; */
  text-align: center;
  background-color: #f2f3f5;
}
/* 自己发送消息的样式 */
.dt-chat-content-self .dt-chat-content-name img {
  margin-left: 10px;
  margin-right: 0;
}
.dt-chat-content-self .dt-chat-content-name em {
  margin-top: 5px;
}
.dt-chat-content-self .dt-chat-content-words-box {
  background-color: #d6e4ff;
}
.dt-chat-content-self .dt-chat-content-words,
.dt-chat-content-self .dt-chat-content-name {
  color: #1f1f1f;
}
/* 语音消息未读样式 */
.dt-chat-content-words-origin {
  width: 8px;
  height: 8px;
  background: #f5222d;
  border-radius: 50%;
  display: inline-block;
  /* margin-left: 10px; */
  position: absolute;
  top: 18px;
  transform: translateY(-50%);
  right: -20px;
}
/* 头像样式 */
.dt-chat-content-headimg {
  position: relative;
  display: inline-block;
  cursor: pointer;
  width: 26px;
  height: 26px;
  margin-right: 5px;
  vertical-align: middle;
}

.dt-chat-content-headimg .el-image {
  width: 26px;
  height: 26px;
  border-radius: 50%;
}
.dt-chat-content-headimg .el-image >>> img {
  width: auto;
  height: auto;
}
.dt-chat-content-headimg .el-image .image-slot {
  text-align: center;
  display: flex;
  flex-direction: column;
  justify-content: center;
  height: 100%;
}
.dt-chat-content-headimg ul {
  border: 1px solid #e1e6f0;
  border-radius: 2px;
  position: absolute;
  left: 34px;
  top: 25px;
  background-color: #fff;
  z-index: 10;
}
.dt-chat-content-headimg ul.up {
  bottom: 80%;
  top: auto;
}
.dt-chat-content-headimg li {
  padding: 0 10px;
  height: 30px;
  line-height: 30px;
  cursor: pointer;
  color: #1f1f1f;
  white-space: nowrap;
}
.dt-chat-content-headimg li:hover {
  background-color: #f0f7ff;
}
.dt-chat-content-headimg .dt-chat-content-name-img {
  position: absolute;
  left: 12px;
  bottom: 0;
  width: 14px;
  height: 14px;
}
.dt-chat-content-name-imgat {
  background: url(/skb/img/@-14×14.svg);
}
.dt-chat-content-name-imgsl {
  background: url(/skb/img/tab-sl.png);
}
/* 头像样式 */
/* 个人信息页 */
.dt-home-info {
  position: absolute;
  top: -3px;
  left: 30px;
  border-radius: 8px;
  width: 312px;
  z-index: 11;
}
.dt-home-info.left {
  top: -3px;
  left: -318px;
}
.dt-home-info.up {
  bottom: 20px;
  top: inherit;
}
.dt-home-info.left.up {
  bottom: 20px;
  top: inherit;
}
.dt-home-info >>> .el-card__body {
  width: 280px;
  min-height: 188px;
  padding: 16px 16px 10px;
}
.dt-home-info dt {
  display: flex;
  display: -webkit-flex;
  padding-bottom: 16px;
  border-bottom: 1px solid #ddd;
}
.dt-home-info .dt-home-head-img {
  display: block;
  margin-right: 18px;
  width: 52px;
  height: 52px;
}
.dt-home-info .dt-home-head-img .el-image {
  width: 52px;
  height: 52px;
  border-radius: 50%;
}
.dt-home-info .dt-home-head-img .el-image >>> img {
  width: auto;
  height: auto;
}
.dt-member-item-headimg .el-image .image-slot {
  text-align: center;
  display: flex;
  flex-direction: column;
  justify-content: center;
  height: 100%;
}
.dt-chat-content-headimg {
  cursor: pointer;
}
.dt-home-info .dt-home-realName {
  display: flex;
  display: -webkit-flex;
  flex-direction: column;
  -webkit-justify-content: center;
  justify-content: center;
}
.dt-home-realName h3 {
  color: #1f1f1f;
  height: 22px;
  line-height: 22px;
}
.dt-home-realName div {
  display: flex;
  display: -webkit-flex;
  -webkit-align-items: center;
  align-items: center;
}
.dt-home-realName i {
  display: block;
  margin-left: 4px;
  width: 16px;
  height: 16px;
  background: url(/skb/img/girl.png) no-repeat center;
}
.dt-home-realName i.boy {
  background: url(/skb/img/boy.png) no-repeat center;
}
.dt-home-uid {
  font-size: 12px;
  color: #909399;
  height: 22px;
  line-height: 22px;
}
.dt-home-info dd {
  display: flex;
  display: -webkit-flex;
  flex-direction: column;
  line-height: 20px;
}
.dt-home-info dd div {
  padding: 5px 0px;
  display: flex;
  display: -webkit-flex;
}
.dt-home-info .dt-home-dd {
  padding: 10px 0px;
  border-bottom: 1px solid #ddd;
  margin-bottom: 10px;
}
.dt-home-info .dt-home-label {
  display: block;
  width: 70px;
  color: #909399;
}
.dt-home-info .dt-home-cont {
  width: 210px;
  color: #1f1f1f;
}
.dt-home-info >>> .el-loading-parent--relative {
  top: 100px;
}
/* 个人信息页 */
/*聊天记录的用户名称 */
.dt-chat-content-name {
  position: relative;
  display: inline-block;
}
.dt-chat-content-name em {
  line-height: 1.7;
}

.dt-chat-content-name {
  font-size: 14px;
  color: #1f1f1f;
}
/*聊天记录的用户名称 */
/*聊天记录的消息展示 */
.dt-chat-content-words-at {
  color: #fa884e;
}
.dt-chat-content-words-sl {
  color: #9254de;
  margin-right: 6px;
}
/* 单一回执铃铛样式 */
.dt-chat-content-words-at-receipt {
  /* width: 16px;
  height: 16px; */
  display: inline-block;
  color: #2f54eb;
  margin-left: 10px;
  line-height: 0;
  padding-top: 2px;
}
.dt-chat-content-words-at-receipt > em {
  font-size: 16px;
}
.dt-chat-content-words-at-receipt-circle {
  width: 15px;
  height: 15px;
  border: 1px solid #85a5ff;
  border-radius: 8px;
  display: inline-block;
  box-sizing: border-box;
}
.dt-chat-content-words-at-check {
  /* width: 16px;
  height: 16px; */
  display: inline-block;
  color: #909399;
  margin-left: 10px;
  line-height: 0;
  padding-top: 2px;
}
.dt-chat-content-words-at-check em.el-icon-circle-check {
  line-height: 0;
}
.dt-chat-content-words-at-receipt em.el-icon-message-solid {
  line-height: 0;
}
.dt-chat-content-words-at-check > em {
  font-size: 16px;
}
/* 单一回执图片的时候头部标题样式 */
.dt-chat-content-words-receipt-tip {
  margin: 0 0 6px 0;
  font-size: 14px;
  color: #fa884e;
  line-height: 1.5;
}
/* 单一回执图片的时候头部标题样式 */
/* 单一回执文件的时候卡片的样式 */
.dt-chat-content-words-receipt-card {
  width: 316px;
  box-sizing: border-box;
  padding: 12px 12px;
  background-color: #fff;
  /* border-radius: 8px; */
  border: 1px solid #e9eef7;
  display: flex;
  cursor: pointer;
}
.dt-chat-content-words-receipt-card img {
  width: 40px;
  height: 40px;
  margin-right: 8px;
}
.dt-chat-content-words-receipt-card p {
  font-size: 14px;
  color: #1f1f1f;
  line-height: 1.5;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  overflow: hidden;
  text-overflow: ellipsis;
}
.dt-chat-content-words-receipt-card p:nth-of-type(2) {
  font-size: 12px;
}
.mb4 {
  margin-bottom: 2px;
}
p.colorb-3 {
  color: #909399;
}
/* 单一回执文件的时候卡片的样式 */
.dt-chat-content-words-bold {
  font-weight: bold;
}
.dt-chat-content-words {
  margin: 0 35px 6px;
  display: flex;
  align-items: center;
}
.dt-chat-content-words-box {
  position: relative;
  background-color: #fff;
  border-radius: 8px;
  display: inline-block;
  padding: 8px 12px;
  font-size: 14px;
  color: #1f1f1f;
  word-break: break-word;
  border-top-left-radius: 0;
}
.dt-chat-content-words .el-image {
  width: 100px;
  height: 100px;
  cursor: pointer;
  vertical-align: top;
  margin: 2px;
}
.dt-chat-content-words .el-image >>> img {
  width: auto;
  height: auto;
}

.dt-chat-content-words .el-image .image-slot {
  text-align: center;
  display: flex;
  flex-direction: column;
  justify-content: center;
  height: 100%;
}
.dt-chat-content-words .dt-chat-1imgs .el-image {
  width: auto;
  height: auto;
}
.dt-chat-content-words .dt-chat-1imgs .el-image >>> img {
  max-width: 650px;
}
.dt-chat-content-words em,
.dt-chat-content-words a {
  line-height: 1.7;
  cursor: pointer;
}
.dt-chat-content-words .align-top {
  vertical-align: top;
}
.dt-chat-content-words .dt-mess-file {
  font-size: 14px;
  color: #597ef7;
}
.dt-chat-content-words em >>> .dt-chat-content-target-link {
  color: #597ef7;
}
.dt-chat-content-words em >>> .dt-chat-content-target-link:hover {
  text-decoration: underline;
}
.dt-chat-content-words > a {
  color: #597ef7;
  font-size: 12px;
  margin-left: 5px;
}
.dt-chat-content-words > i {
  color: #597ef7;
}
/*聊天记录的消息展示 */
/* 单张图片时候的样式 */
.dt-chat-content-words .dt-chat-1imgs .el-image {
  width: auto;
  height: auto;
}
.dt-chat-content-words .dt-chat-1imgs .el-image >>> img {
  max-width: 650px;
}
/* 单张图片时候的样式 */
/* 多张图片时候的样式 */
.dt-chat-9imgs {
  max-width: 312px;
}
/* 多张图片时候的样式 */
/* 消息内容是文件的时候样式 */
.dt-chat-content-words .dt-mess-file {
  font-size: 14px;
  color: #597ef7;
}
/* 消息内容是文件的时候样式 */
/* 回执消息类型的卡片样式 */
.dt-chat-content-words-card {
  width: 280px;
}
.box-card {
  padding: 16px 14px 12px 14px;
}
.box-card >>> .el-card__body {
  padding: 0;
}
.dt-chat-content-words-card-title {
  font-size: 14px;
  color: #1f1f1f;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  font-weight: bold;
  line-height: 1.5;
}
.dt-chat-content-words-card-dec {
  font-size: 12px;
  color: #606266;
  margin-top: 10px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  line-height: 1.5;
}
.dt-chat-content-words-card-dec.mt8 {
  margin-top: 8px;
}
.dt-chat-content-words-card-dec.mb12 {
  margin-bottom: 12px;
}

.dt-chat-content-words-card-receipt.dt-chat-content-words-card-btn.mt12 {
  margin-top: 12px;
}
.dt-chat-content-words-card-receipt {
  font-size: 12px;
  color: #2f54eb;
}
.dt-chat-content-words-card-receipt >>> .is-disabled {
  background-color: #adc6ff;
  border-color: #adc6ff;
}
.dt-chat-content-words-card-line {
  height: 1px;
  background-color: #e9eef7;
}
.dt-chat-content-words-card-btn {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-top: 12px;
}
.dt-chat-content-words-card {
  cursor: pointer;
}
/* 回执消息类型的卡片样式 */
/* 消息记录底部时间样式 */
.dt-chat-content-time {
  margin: 0 34px 0px 34px;
}
.dt-chat-content-chatTime {
  font-size: 12px;
  color: #999;
  margin-right: 10px;
}
.dt-chat-content-replyclick {
  font-size: 12px;
  color: #597ef7;
  margin-left: 10px;
}
.dt-report-tip {
  /* margin-left: 10px; */
  font-size: 12px;
  color: #909399;
}
.dt-report-tip .el-icon-warning-outline {
  margin-right: 2px;
}
/* 消息记录底部时间样式 */
/* 聊天样式回到原消息的闪烁动画 */
/* 闪烁的动画 */
@keyframes blink-background {
  0% {
    background-color: rgba(255, 255, 255, 0); /* 白色透明 */
  }
  10% {
    background-color: rgba(214, 228, 255, 1); /* 半透明灰色 */
  }
  40% {
    background-color: rgba(214, 228, 255, 1); /* 保持半透明灰色 */
  }
  70% {
    background-color: rgba(255, 255, 255, 0); /* 变回白色透明 */
  }
  100% {
    background-color: rgba(255, 255, 255, 0); /* 保持白色透明 */
  }
}

.flashing {
  animation: blink-background 1s linear 1; /* 应用动画，无限循环 */
}
/* 聊天样式回到原消息的闪烁动画 */
/* 评论消息输入框样式 */
.dt-chat-content-reply {
  margin: 8px 0px 0px 34px;
}
.dt-chat-content-replybtn {
  width: 70%;
  height: 28px;
}
.dt-chat-content-reply > .el-textarea {
  width: 70%;
  margin-bottom: 8px;
  padding-bottom: 0;
}
.dt-chat-content-reply > .el-textarea >>> textarea {
  resize: none;
  height: 55px;
}
.dt-chat-content-replybtn i {
  font-size: 18px;
  color: #606266;
  cursor: pointer;
  float: left;
  margin-top: 5px;
  margin-right: 5px;
}
.dt-chat-content-replybtn i img {
  display: block;
}

/* 评论消息输入框样式 */
/*评论消息展示框样式*/
.dt-chat-content-reply-info {
  max-height: 490px;
  background-color: #e6ebf4;
  overflow: auto;
  margin: 6px 34px;
}

.dt-chat-content-reply-info-list {
  margin-top: 8px;
  margin-bottom: 8px;
}
.dt-chat-content-reply-info-review {
  float: right;
  margin-top: -20px;
  margin-right: 10px;
}
.dt-chat-content-reply-info-review >>> a {
  color: #597ef7;
  font-size: 12px;
}
.dt-chat-content-reply-userInfo {
  margin: 0 10px 4px 10px;
  font-size: 12px;
  line-height: 1.5;
}

.dt-chat-content-reply-info-name {
  font-size: 12px;
  color: #333;
  /* margin-right: 6px; */
}

.dt-chat-content-reply-info-words {
  font-size: 12px;
  color: #333333;
  word-break: break-all;
  /* line-height: 20px; */
}
.dt-chat-content-reply-info-words >>> .el-image {
  display: none;
}
.dt-chat-content-reply-info-words >>> .dt-chat-content-target-link,
.dt-chat-content-reply-info-words a {
  color: #597ef7;
}
.dt-chat-content-reply-info-words >>> .dt-chat-content-target-link:hover {
  text-decoration: underline;
}
.dt-chat-content-reply-info-words-sl {
  color: #9254de;
}
.dt-chat-content-reply-time {
  font-size: 12px;
  color: #999999;
  margin: 0 10px 8px 10px;
}
/*评论消息展示框样式*/
/* 聊天记录每一条的样式 */
/* 回执消息查看详情样式 */
.dt-receipt-content {
  display: flex;
  height: 480px;
}
.dt-receipt-content-left {
  width: 680px;
  border-right: 1px solid #e9eef7;
  padding: 0 20px;
  box-sizing: border-box;
  position: relative;
  overflow: auto;
  display: flex;
  flex-direction: column;
}
.dt-receipt-content-right {
  width: 360px;
  padding: 0 20px;
  box-sizing: border-box;
  overflow: auto;
}
.dt-talk-panel >>> .el-dialog {
  height: 540px;
}
.dt-talk-panel >>> .el-dialog__header {
  text-align: left;
  padding: 0 20px;
  line-height: 60px;
  box-sizing: border-box;
  height: 60px;
  font-size: 18px;
  color: #1f1f1f;
  border-bottom: 1px solid #e9eef7;
}
.dt-talk-panel >>> .el-dialog__body {
  padding: 0;
  height: 480px;
}
.dt-receipt-content-left-title {
  /* padding: 0 20px; */
  margin-top: 20px;
  font-size: 20px;
  color: #1f1f1f;
  line-height: 28px;
  text-align: left;
}
.dt-receipt-content-left-join {
  margin-top: 16px;
  text-align: left;
  /* padding: 0 20px 20px 20px; */
  padding-bottom: 20px;
  border-bottom: 1px solid #e9eef7;
}
.dt-receipt-content-left-join em {
  font-size: 16px;
  color: #909399;
}
.dt-receipt-content-left-join span {
  font-size: 14px;
  color: #1f1f1f;
  line-height: 1.5;
}
.dt-receipt-content-left-dec {
  /* padding: 0 20px; */
  text-align: left;
  margin-top: 20px;
  display: flex;
  /* align-items: center; */
  line-height: 22px;
}
.dt-receipt-content-left-dec > em {
  width: 100px; /* 设置em的宽度为100px */
  flex-shrink: 0; /* 防止em在flex布局中收缩 */
  font-size: 14px;
  color: #606266;
}
.dt-receipt-content-left-dec > span {
  flex: 1;
  font-size: 14px;
  color: #1f1f1f;
  line-height: 22px;
}
.dt-receipt-content-left-file {
  /* padding: 0 20px; */
  text-align: left;
  margin-top: 20px;
  display: flex;
  margin-bottom: 28px;

  /* align-items: center; */
}
.dt-receipt-content-left-file-left {
  width: 100px; /* 设置em的宽度为100px */
  flex-shrink: 0; /* 防止em在flex布局中收缩 */
  font-size: 14px;
  color: #606266;
  padding-top: 4px;
  line-height: 28px;
}
.dt-receipt-content-left-file-right {
  flex: 1;
  padding: 4px;
  border: 1px solid #e9eef7;
}
.dt-receipt-content-left-file-right-none {
  flex: 1;
  padding: 4px 0;
  line-height: 28px;
  color: #1f1f1f;
}
.dt-receipt-content-left-file-right > div {
  padding: 0 4px;
  line-height: 28px;
  border-radius: 4px;
}
.dt-receipt-content-left-file-right > div:hover {
  background-color: #f0f5ff;
}
.dt-receipt-content-left-file-right > div > em {
  font-size: 14px;
  color: #c0c4cc;
}
.dt-receipt-content-left-file-right > div > span {
  font-size: 12px;
  color: #1f1f1f;
}
.dt-receipt-content-left-file-right > div > span:nth-of-type(2) {
  float: right;
}
.dt-receipt-content-left-file-right >>> .el-button {
  padding: 0;
  font-size: 12px;
}
.dt-receipt-content-right-top {
  font-size: 12px;
  color: #909399;
  text-align: left;
}
.dt-receipt-content-right-receipt-list {
  display: flex;
  justify-content: space-between;
  margin-top: 8px;
  height: 32px;
  border-bottom: 1px solid #e9eef7;
  align-items: center;
}
.dt-receipt-content-right-receipt-list > span {
  font-size: 12px;
  color: #1f1f1f;
}
.dt-receipt-content-right >>> div.cell {
  /* padding: 0; */
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  font-size: 12px;
  color: #1f1f1f;
}
.dt-receipt-content-right >>> .el-table__cell {
  padding: 4px 0;
}
.dt-receipt-content-right >>> .el-table__cell > th.cell {
  color: #909399;
}
.dt-receipt-content-right >>> .el-tabs__header {
  margin-bottom: 10px;
}
.dialog-footer {
  border-top: 1px solid #e9eef7;
  text-align: right;
  padding-right: 20px;
  padding-top: 14px;
  padding-bottom: 14px;
  margin-left: -20px;
  margin-right: -20px;
  margin-top: auto;
  flex-shrink: 0; /* 防止.dialog-footer被压缩 */
  /* text-align: right;
  margin-bottom: 28px; */
}
/* 回执消息查看详情样式 */
/* 举报弹窗样式 */
/* 举报 */
.dt-report-group >>> .el-dialog__body {
  padding: 12px 20px 0px;
}
.dt-report-group h6 {
  font-weight: normal;
}
.dt-report-group .dt-name {
  display: inline-block;
  color: #597ef7;
  margin: 0px 6px;
}
.dt-report-recover {
  margin: 8px 0px 16px;
  padding: 8px 10px;
  background: #f2f3f5;
  line-height: 18px;
  text-align: justify;
  display: flex;
}
.dt-report-radio {
  padding-top: 10px;
  border-top: 1px solid #eee;
}
.dt-report-radio >>> .el-form-item__error {
  top: 80%;
}
.dt-report-group >>> .el-form-item {
  margin-bottom: 12px;
}
.dt-report-group >>> .el-dialog__footer {
  border-top: 1px solid #eee;
  padding: 14px 20px;
}
/* 举报弹窗样式 */
/* 举报 */
/* 艾特 私聊 评论小弹窗 */
.dt-chat-content-chattip {
  position: absolute;
  right: 40px;
  bottom: 10px;
}
.dt-chat-content-chattip li {
  text-align: right;
}
.dt-chat-content-chattip a {
  box-shadow: 0 0 24px rgba(0, 0, 0, 0.2);
  background-color: #fff;
  padding: 0 20px;
  border-radius: 20px;
  height: 34px;
  line-height: 34px;
  display: inline-block;
  margin-top: 10px;
}
.dt-chat-tip-purple {
  color: #9254de;
}
.dt-chat-tip-yellow {
  color: #fa884e;
}
.dt-chat-tip-black {
  color: #666;
}
/* 艾特 私聊 评论小弹窗 */
/* 语音消息样式 */
.dt-chat-content-words-box.dt-chat-content-words-box-voice {
  padding: 0;
}
.voice-message {
  display: inline-block;
  /* position: relative; */
  padding: 0 10px;
  /* background-color: #f2f2f2; */
  border-radius: 5px;
  max-width: 260px;
  min-width: 46px;
  height: 36px;
  line-height: 36px;
  text-align: left;
  font-size: 0px;
}

.voice-message .icon {
  display: inline-block;
  width: 16px;
  height: 16px;
  background-image: url('/skb/img/voice-1.svg'); /* 微信语音消息的麦克风图标 */
  background-size: cover;
  vertical-align: middle;
  transition: background-image 0.4s ease-in-out; /* 动画效果 */
}
.voice-message .icon.animation {
  animation: wave-animation 1.2s infinite linear;
}
.voice-message .icon.paused {
  animation-play-state: paused;
}

.voice-message .audio-length {
  display: inline-block;
  margin-left: 8px;
  vertical-align: middle;
  font-size: 14px;
}
.voice-text {
  max-width: 280px;
  padding: 0 10px;
  box-sizing: border-box;
  /* border-top: 1px solid #e9eef7; */
}
.voice-text p {
  padding: 8px 0px;
  border-top: 1px solid #e9eef7;
  line-height: 1.5;
}
.voice-text >>> .el-loading-parent--relative {
  height: 16px;
}
.voice-text >>> .el-loading-spinner {
  top: 80%;
}
.voice-text >>> .el-icon-loading {
  font-size: 16px;
  color: #1f1f1f;
}
@keyframes wave-animation {
  0% {
    background-image: url('/skb/img/voice-1.svg');
  }
  1% {
    background-image: url('/skb/img/voice-3.svg');
  }
  33% {
    background-image: url('/skb/img/voice-2.svg');
  }
  100% {
    background-image: url('/skb/img/voice-1.svg');
  }
}
/* .voice-message .wave {
  position: absolute;
  bottom: 0;
  left: 0;
  width: 100%;
  height: 6px;
  background: linear-gradient(to right, #f2f2f2 5%, #9e9e9e 45%, #f2f2f2 55%);
  background-size: 20px 6px;
  animation: wave-animation 1s infinite linear;
}

@keyframes wave-animation {
  0% {
    background-position: 0 0;
  }
  100% {
    background-position: 20px 0;
  }
} */
/* 语音消息样式 */
</style>
